Readme index'ler eklendi.
This commit is contained in:
1
.serena/.gitignore
vendored
Normal file
1
.serena/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/cache
|
||||||
84
.serena/project.yml
Normal file
84
.serena/project.yml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# list of languages for which language servers are started; choose from:
|
||||||
|
# al bash clojure cpp csharp csharp_omnisharp
|
||||||
|
# dart elixir elm erlang fortran go
|
||||||
|
# haskell java julia kotlin lua markdown
|
||||||
|
# nix perl php python python_jedi r
|
||||||
|
# rego ruby ruby_solargraph rust scala swift
|
||||||
|
# terraform typescript typescript_vts zig
|
||||||
|
# Note:
|
||||||
|
# - For C, use cpp
|
||||||
|
# - For JavaScript, use typescript
|
||||||
|
# Special requirements:
|
||||||
|
# - csharp: Requires the presence of a .sln file in the project folder.
|
||||||
|
# When using multiple languages, the first language server that supports a given file will be used for that file.
|
||||||
|
# The first language is the default language and the respective language server will be used as a fallback.
|
||||||
|
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
||||||
|
languages:
|
||||||
|
- typescript
|
||||||
|
|
||||||
|
# the encoding used by text files in the project
|
||||||
|
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
||||||
|
encoding: "utf-8"
|
||||||
|
|
||||||
|
# whether to use the project's gitignore file to ignore files
|
||||||
|
# Added on 2025-04-07
|
||||||
|
ignore_all_files_in_gitignore: true
|
||||||
|
|
||||||
|
# list of additional paths to ignore
|
||||||
|
# same syntax as gitignore, so you can use * and **
|
||||||
|
# Was previously called `ignored_dirs`, please update your config if you are using that.
|
||||||
|
# Added (renamed) on 2025-04-07
|
||||||
|
ignored_paths: []
|
||||||
|
|
||||||
|
# whether the project is in read-only mode
|
||||||
|
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
||||||
|
# Added on 2025-04-18
|
||||||
|
read_only: false
|
||||||
|
|
||||||
|
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
||||||
|
# Below is the complete list of tools for convenience.
|
||||||
|
# To make sure you have the latest list of tools, and to view their descriptions,
|
||||||
|
# execute `uv run scripts/print_tool_overview.py`.
|
||||||
|
#
|
||||||
|
# * `activate_project`: Activates a project by name.
|
||||||
|
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
||||||
|
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
||||||
|
# * `delete_lines`: Deletes a range of lines within a file.
|
||||||
|
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
||||||
|
# * `execute_shell_command`: Executes a shell command.
|
||||||
|
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
||||||
|
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
||||||
|
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
||||||
|
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
||||||
|
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
||||||
|
# * `initial_instructions`: Gets the initial instructions for the current project.
|
||||||
|
# Should only be used in settings where the system prompt cannot be set,
|
||||||
|
# e.g. in clients you have no control over, like Claude Desktop.
|
||||||
|
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
||||||
|
# * `insert_at_line`: Inserts content at a given line in a file.
|
||||||
|
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
||||||
|
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
||||||
|
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
||||||
|
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
||||||
|
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
||||||
|
# * `read_file`: Reads a file within the project directory.
|
||||||
|
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
||||||
|
# * `remove_project`: Removes a project from the Serena configuration.
|
||||||
|
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
||||||
|
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
||||||
|
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
||||||
|
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
||||||
|
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
||||||
|
# * `switch_modes`: Activates modes by providing a list of their names
|
||||||
|
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
||||||
|
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
||||||
|
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
||||||
|
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
||||||
|
excluded_tools: []
|
||||||
|
|
||||||
|
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
||||||
|
# (contrary to the memories, which are loaded on demand).
|
||||||
|
initial_prompt: ""
|
||||||
|
|
||||||
|
project_name: "ytp"
|
||||||
|
included_optional_tools: []
|
||||||
191
README.md
Normal file
191
README.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# Yakıt Takip Sistemi (YTP)
|
||||||
|
|
||||||
|
**Türk Silahlı Kuvvetleri Akaryakıt İkmal ve Yönetim Sistemi**
|
||||||
|
|
||||||
|
TSK bünyesindeki akaryakıt istasyonlarında yakıt ikmal süreçlerini dijital ortama taşıyan, rol bazlı yetkilendirme ile stok takibi ve fiş yönetimi sağlayan modern bir web uygulaması.
|
||||||
|
|
||||||
|
## 🚀 Özellikler
|
||||||
|
|
||||||
|
### 🎯 Rol Bazlı Erişim Sistemi
|
||||||
|
- **Admin**: Tüm sistem kullanıcılarını ve kaynakları yönetir
|
||||||
|
- **Yakıt Sorumlusu**: Yakıt fişleri oluşturur, süreci yönetir
|
||||||
|
- **Mal Sorumlusu**: Atanan yakıt fişlerini onaylar/reddeder
|
||||||
|
|
||||||
|
### ⚡ Gerçek Zamanlı İşlemler
|
||||||
|
- Socket.IO tabanlı anında bildirimler
|
||||||
|
- Otomatik güncellemeler ve durum takibi
|
||||||
|
- Çoklu kullanıcı desteği
|
||||||
|
|
||||||
|
### 📊 Kapsamlı Yönetim
|
||||||
|
- **Araç Yönetimi**: Plaka, marka, model, yıl bilgileri
|
||||||
|
- **Birim Yönetimi**: Adres, STK/BTK, sorumlu kişi bilgileri
|
||||||
|
- **Personel Yönetimi**: Yakıt personeli kayıt ve takibi
|
||||||
|
- **Fiş Yönetimi**: Oluşturma, onay, red ve arşivleme
|
||||||
|
|
||||||
|
### 📋 Dijital Fiş Sistemi
|
||||||
|
- Otomatik fiş numarası üretimi
|
||||||
|
- PDF formatında resmi fiş çıkarma
|
||||||
|
- Tüm kuvvetler için destek (MSB, K.K.K., Dz.K.K., Hv.K.K., SGK, Gnkur. Bşk., Hrt.Gn.K.)
|
||||||
|
|
||||||
|
### 🔒 Güvenlik
|
||||||
|
- Token bazlı oturum yönetimi
|
||||||
|
- Rol bazlı yetkilendirme
|
||||||
|
- SQLite veritabanı güvenliği
|
||||||
|
|
||||||
|
## 🏗️ Teknik Mimari
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- **Node.js + Express**: REST API sunucusu
|
||||||
|
- **Socket.IO**: Gerçek zamanlu iletişim
|
||||||
|
- **SQLite3**: Hafif veritabanı
|
||||||
|
- **PDFKit**: PDF belge oluşturma
|
||||||
|
- **CORS**: Çapraz kaynak paylaşımı
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- **Svelte 4**: Modern ve reaktif UI kütüphanesi
|
||||||
|
- **Vite**: Hızlı geliştirme ve build aracı
|
||||||
|
- **Socket.IO Client**: Gerçek zamanlu istemci
|
||||||
|
- **Font Awesome**: İkon kütüphanesi
|
||||||
|
|
||||||
|
### Veritabanı
|
||||||
|
- **SQLite**: Hafif ve taşınabilir veritabanı
|
||||||
|
- **Foreign Key** desteği ile veri bütünlüğü
|
||||||
|
- **Otomatik yedekleme ve migration
|
||||||
|
|
||||||
|
## 📁 Proje Yapısı
|
||||||
|
|
||||||
|
```
|
||||||
|
ytp/
|
||||||
|
├── client/ # Frontend uygulaması
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── components/ # Svelte bileşenleri
|
||||||
|
│ │ │ ├── LoginView.svelte # Giriş ekranı
|
||||||
|
│ │ │ ├── AdminPanel.svelte # Admin paneli
|
||||||
|
│ │ │ ├── FuelManagerPanel.svelte # Yakıt sorumlusu paneli
|
||||||
|
│ │ │ ├── InventoryManagerPanel.svelte # Mal sorumlusu paneli
|
||||||
|
│ │ │ └── RoleWelcome.svelte # Rol karşılama ekranı
|
||||||
|
│ │ ├── lib/ # Yardımcı kütüphaneler
|
||||||
|
│ │ │ └── numberToWordsTr.js # Sayıdan metne çeviri
|
||||||
|
│ │ ├── api.js # API istemcisi
|
||||||
|
│ │ ├── app.css # Ana stil dosyası
|
||||||
|
│ │ ├── main.js # Uygulama giriş noktası
|
||||||
|
│ │ └── App.svelte # Ana uygulama bileşeni
|
||||||
|
│ ├── package.json # Frontend bağımlılıkları
|
||||||
|
│ ├── vite.config.js # Vite yapılandırması
|
||||||
|
│ └── svelte.config.js # Svelte yapılandırması
|
||||||
|
├── server/ # Backend uygulaması
|
||||||
|
│ ├── index.js # Express sunucusu
|
||||||
|
│ ├── db.js # Veritabanı işlemleri
|
||||||
|
│ └── db-init.js # Veritabanı başlangıç
|
||||||
|
├── data/ # Veritabanı dosyaları
|
||||||
|
│ └── app.db # SQLite veritabanı
|
||||||
|
└── package.json # Proje bağımlılıkları
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Kurulum
|
||||||
|
|
||||||
|
### Gereksinimler
|
||||||
|
- Node.js 16+
|
||||||
|
- npm 7+
|
||||||
|
- SQLite3 (otomatik yüklenir)
|
||||||
|
|
||||||
|
### Adım 1: Projeyi Klonlayın
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd ytp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 2: Bağımlılıkları Yükleyin
|
||||||
|
```bash
|
||||||
|
# Ana proje bağımlılıkları
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Frontend bağımlılıkları
|
||||||
|
cd client
|
||||||
|
npm install
|
||||||
|
cd ..
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 3: Veritabanını Başlatın
|
||||||
|
```bash
|
||||||
|
npm run prepare:db
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 4: Uygulamayı Çalıştırın
|
||||||
|
```bash
|
||||||
|
# Geliştirme modunda çalıştırma
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Veya sadece sunucuyu başlatma
|
||||||
|
npm run start:server
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 5: Tarayıcıda Açın
|
||||||
|
Uygulama `http://localhost:5005` adresinde çalışacaktır.
|
||||||
|
|
||||||
|
## 👤 Varsayılan Kullanıcılar
|
||||||
|
|
||||||
|
Sistem ilk kurulumda aşağıdaki test kullanıcılarını oluşturur:
|
||||||
|
|
||||||
|
| Rol | Kullanıcı Adı | Şifre | Açıklama |
|
||||||
|
|-----|--------------|-------|----------|
|
||||||
|
| Admin | `admin` | `Admin!123` | Sistem yöneticisi |
|
||||||
|
| Yakıt Sorumlusu | `yakitsorum` | `Yakit@123` | Yakıt fişi oluşturabilir |
|
||||||
|
| Mal Sorumlusu | `malsorum1` | `Mal@123` | Fiş onay/reddeder |
|
||||||
|
|
||||||
|
## 📚 API Dokümantasyonu
|
||||||
|
|
||||||
|
### Kimlik Doğrulama
|
||||||
|
- `POST /api/auth/login` - Giriş
|
||||||
|
- `POST /api/auth/logout` - Çıkış
|
||||||
|
- `GET /api/session` - Oturum bilgisi
|
||||||
|
|
||||||
|
### Yönetim (Admin)
|
||||||
|
- `GET/POST/PUT/DELETE /api/inventory-managers` - Mal sorumluları
|
||||||
|
- `GET/POST/PUT/DELETE /api/vehicles` - Araçlar
|
||||||
|
- `GET/POST/PUT/DELETE /api/units` - Birlikler
|
||||||
|
- `GET/POST/PUT/DELETE /api/fuel-personnel` - Personel
|
||||||
|
|
||||||
|
### Yakıt İşlemleri
|
||||||
|
- `GET /api/fuel/resources` - Kaynak bilgileri
|
||||||
|
- `GET /api/fuel-slips` - Tüm fişler
|
||||||
|
- `POST /api/fuel-slips` - Fiş oluştur
|
||||||
|
- `GET /api/fuel-slips/:id/pdf` - PDF indir
|
||||||
|
- `PATCH /api/fuel-slips/:id/status` - Durum güncelle
|
||||||
|
|
||||||
|
## 🔧 Geliştirme
|
||||||
|
|
||||||
|
### Proje Özellikleri
|
||||||
|
- **Responsive Tasarım**: Mobil uyumlu arayüz
|
||||||
|
- **Real-time Updates**: Socket.IO ile anında bildirimler
|
||||||
|
- **Type Safety**: JavaScript tabanlı yapı
|
||||||
|
- **Modern CSS**: Flexbox/Grid tabanlı responsive design
|
||||||
|
- **Error Handling**: Kapsamlı hata yönetimi
|
||||||
|
- **Session Management**: Güvenli oturum yönetimi
|
||||||
|
|
||||||
|
### Kod Standartları
|
||||||
|
- ESLint kullanımı önerilir
|
||||||
|
- Bileşen tabanlı geliştirme
|
||||||
|
- Clean Code prensipleri
|
||||||
|
- Responsive first design
|
||||||
|
|
||||||
|
## 📄 Lisans
|
||||||
|
|
||||||
|
Bu proje ISC lisansı ile lisanslanmıştır.
|
||||||
|
|
||||||
|
## 🤝 Katkıda Bulunma
|
||||||
|
|
||||||
|
1. Projeyi fork edin
|
||||||
|
2. Geliştirme branch'ini oluşturun (`git checkout -b feature/AmazingFeature`)
|
||||||
|
3. Değişikliklerinizi commit edin (`git commit -m 'Add some AmazingFeature'`)
|
||||||
|
4. Branch'e push edin (`git push origin feature/AmazingFeature`)
|
||||||
|
5. Pull Request oluşturun
|
||||||
|
|
||||||
|
## 📞 Destek
|
||||||
|
|
||||||
|
Geliştirici: [İletişim Bilgileri]
|
||||||
|
Proje Sayfası: [GitHub Repository]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Not**: Bu proje TSK bünyesindeki akaryakıt yönetim süreçlerini dijitalleştirmek amacıyla geliştirilmiş örnek bir uygulamadır.
|
||||||
BIN
data/app.db
BIN
data/app.db
Binary file not shown.
659
docs/API.md
Normal file
659
docs/API.md
Normal file
@@ -0,0 +1,659 @@
|
|||||||
|
# YTP API Dokümantasyonu
|
||||||
|
|
||||||
|
Yakıt Takip Sistemi REST API endpoints ve WebSocket olayları için kapsamlı dokümantasyon.
|
||||||
|
|
||||||
|
## 📋 İçerik
|
||||||
|
|
||||||
|
- [Genel Bakış](#genel-bakış)
|
||||||
|
- [Kimlik Doğrulama](#kimlik-doğrulama)
|
||||||
|
- [Admin API](#admin-api)
|
||||||
|
- [Yakıt Sorumlusu API](#yakıt-sorumlusu-api)
|
||||||
|
- [Mal Sorumlusu API](#mal-sorumlusu-api)
|
||||||
|
- [WebSocket Olayları](#websocket-olayları)
|
||||||
|
- [Hata Kodları](#hata-kodları)
|
||||||
|
|
||||||
|
## 🔧 Genel Bakış
|
||||||
|
|
||||||
|
### Base URL
|
||||||
|
```
|
||||||
|
http://localhost:5005/api
|
||||||
|
```
|
||||||
|
|
||||||
|
### İstek Formatı
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **Authorization**: `X-Session-Token` header
|
||||||
|
|
||||||
|
### Yanıt Formatı
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Başarılı mesaj",
|
||||||
|
"data": { ... },
|
||||||
|
"error": "Hata mesajı (varsa)"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 Kimlik Doğrulama
|
||||||
|
|
||||||
|
### POST /auth/login
|
||||||
|
Kullanıcı girişi için endpoint.
|
||||||
|
|
||||||
|
**İstek:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"username": "admin",
|
||||||
|
"password": "Admin!123"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Başarılı Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"token": "a1b2c3d4e5f6...",
|
||||||
|
"user": {
|
||||||
|
"id": 1,
|
||||||
|
"username": "admin",
|
||||||
|
"role": "admin",
|
||||||
|
"displayName": "Istasyon Admini"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Hata Yanıtları:**
|
||||||
|
- `400` - Kullanıcı adı veya şifre eksik
|
||||||
|
- `401` - Kullanıcı adı veya şifre hatalı
|
||||||
|
- `500` - Sunucu hatası
|
||||||
|
|
||||||
|
### POST /auth/logout
|
||||||
|
Oturumu kapatma.
|
||||||
|
|
||||||
|
**Headers:**
|
||||||
|
```
|
||||||
|
X-Session-Token: <token>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Oturum kapatildi."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### GET /session
|
||||||
|
Mevcut oturum bilgilerini getirme.
|
||||||
|
|
||||||
|
**Headers:**
|
||||||
|
```
|
||||||
|
X-Session-Token: <token>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"id": 1,
|
||||||
|
"username": "admin",
|
||||||
|
"role": "admin",
|
||||||
|
"displayName": "Istasyon Admini"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 👑 Admin API
|
||||||
|
|
||||||
|
### Mal Sorumluları Yönetimi
|
||||||
|
|
||||||
|
#### GET /inventory-managers
|
||||||
|
Tüm mal sorumlularını listeler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"managers": [
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"username": "malsorum1",
|
||||||
|
"displayName": "Mal Sorumlusu 1",
|
||||||
|
"createdAt": "2024-01-01T10:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### POST /inventory-managers
|
||||||
|
Yeni mal sorumlusu oluşturur.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**İstek:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"username": "malsorum2",
|
||||||
|
"password": "Mal@123",
|
||||||
|
"displayName": "Mal Sorumlusu 2"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yanıt (201):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"manager": {
|
||||||
|
"id": 4,
|
||||||
|
"username": "malsorum2",
|
||||||
|
"displayName": "Mal Sorumlusu 2",
|
||||||
|
"role": "inventory_manager"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PUT /inventory-managers/:id
|
||||||
|
Mal sorumlusunu günceller.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**İstek:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"displayName": "Güncellenmiş İsim",
|
||||||
|
"password": "YeniŞifre123"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### DELETE /inventory-managers/:id
|
||||||
|
Mal sorumlusunu siler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**Yanıt (204)** - No Content
|
||||||
|
|
||||||
|
### Araç Yönetimi
|
||||||
|
|
||||||
|
#### GET /vehicles
|
||||||
|
Tüm araçları listeler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"vehicles": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"brand": "Ford",
|
||||||
|
"model": "Transit",
|
||||||
|
"year": 2021,
|
||||||
|
"plate": "34 AYT 312",
|
||||||
|
"createdAt": "2024-01-01T10:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### POST /vehicles
|
||||||
|
Yeni araç oluşturur.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**İstek:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"brand": "Ford",
|
||||||
|
"model": "Transit",
|
||||||
|
"year": 2021,
|
||||||
|
"plate": "34 AYT 312"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yanıt (201):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"vehicle": {
|
||||||
|
"id": 2,
|
||||||
|
"brand": "Ford",
|
||||||
|
"model": "Transit",
|
||||||
|
"year": 2021,
|
||||||
|
"plate": "34 AYT 312"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PUT /vehicles/:id
|
||||||
|
Araç bilgilerini günceller.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
#### DELETE /vehicles/:id
|
||||||
|
Araç kaydını siler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
### Birlik Yönetimi
|
||||||
|
|
||||||
|
#### GET /units
|
||||||
|
Tüm birlikleri listeler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"units": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Merkez Birlik",
|
||||||
|
"address": "Cumhuriyet Mah. İstasyon Cad. No:12/1 İstanbul",
|
||||||
|
"stk": "STK-4589",
|
||||||
|
"btk": "BTK-9021",
|
||||||
|
"contactName": "Yzb. Murat Kaya",
|
||||||
|
"contactRank": "Yuzbasi",
|
||||||
|
"contactRegistry": "MK4587",
|
||||||
|
"contactIdentity": "25478963210",
|
||||||
|
"contactPhone": "+90 532 456 78 12",
|
||||||
|
"createdAt": "2024-01-01T10:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### POST /units
|
||||||
|
Yeni birlik oluşturur.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**İstek:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Doğu Lojistik Birimi",
|
||||||
|
"address": "Sanayi Mah. Depo Sok. No:8 Erzurum",
|
||||||
|
"stk": "STK-7865",
|
||||||
|
"btk": "BTK-6674",
|
||||||
|
"contactName": "Uzm. Cav. Esra Yilmaz",
|
||||||
|
"contactRank": "Uzman Cavus",
|
||||||
|
"contactRegistry": "EY3345",
|
||||||
|
"contactIdentity": "19876543219",
|
||||||
|
"contactPhone": "+90 532 998 11 44"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PUT /units/:id
|
||||||
|
Birim bilgilerini günceller.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
#### DELETE /units/:id
|
||||||
|
Birim kaydını siler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
### Personel Yönetimi
|
||||||
|
|
||||||
|
#### GET /fuel-personnel
|
||||||
|
Tüm yakıt personelini listeler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"personnel": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"fullName": "Astsb. Cahit Demir",
|
||||||
|
"rank": "Astsubay",
|
||||||
|
"registryNumber": "CD5561",
|
||||||
|
"identityNumber": "14523698741",
|
||||||
|
"phone": "+90 532 223 45 67",
|
||||||
|
"createdAt": "2024-01-01T10:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### POST /fuel-personnel
|
||||||
|
Yeni personel oluşturur.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
**İstek:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"fullName": "Sv. Uzm. Er Ali Korkmaz",
|
||||||
|
"rank": "Sozlesmeli Er",
|
||||||
|
"registryNumber": "AK7812",
|
||||||
|
"identityNumber": "32987456100",
|
||||||
|
"phone": "+90 555 893 22 10"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PUT /fuel-personnel/:id
|
||||||
|
Personel bilgilerini günceller.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
#### DELETE /fuel-personnel/:id
|
||||||
|
Personel kaydını siler.
|
||||||
|
|
||||||
|
**Yetki:** Admin
|
||||||
|
|
||||||
|
## ⚡ Yakıt Sorumlusu API
|
||||||
|
|
||||||
|
### GET /fuel/resources
|
||||||
|
Yakıt fişi oluşturmak için gerekli kaynakları getirir.
|
||||||
|
|
||||||
|
**Yetki:** Yakıt Sorumlusu
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"forces": ["MSB", "K.K.K.", "Dz.K.K.", "Hv.K.K.", "SGK", "Gnkur. Bşk.", "Hrt.Gn.K."],
|
||||||
|
"vehicles": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"brand": "Ford",
|
||||||
|
"model": "Transit",
|
||||||
|
"year": 2021,
|
||||||
|
"plate": "34 AYT 312"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"units": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Merkez Birlik",
|
||||||
|
"address": "Cumhuriyet Mah. İstasyon Cad. No:12/1 İstanbul"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"personnel": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"fullName": "Astsb. Cahit Demir",
|
||||||
|
"rank": "Astsubay",
|
||||||
|
"registryNumber": "CD5561",
|
||||||
|
"phone": "+90 532 223 45 67"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inventoryManagers": [
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"displayName": "Mal Sorumlusu 1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### GET /fuel-slips
|
||||||
|
Tüm yakıt fişlerini listeler.
|
||||||
|
|
||||||
|
**Yetki:** Yakıt Sorumlusu
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"slips": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"slipNumber": 1,
|
||||||
|
"createdAt": "2024-01-01T10:00:00Z",
|
||||||
|
"slipDate": "2024-01-01",
|
||||||
|
"force": "MSB",
|
||||||
|
"unitId": 1,
|
||||||
|
"unitName": "Merkez Birlik",
|
||||||
|
"vehicleId": 1,
|
||||||
|
"vehicleDescription": "Ford Transit",
|
||||||
|
"plate": "34 AYT 312",
|
||||||
|
"fuelAmountNumber": 50,
|
||||||
|
"fuelAmountText": "Elli",
|
||||||
|
"fuelType": "Benzin",
|
||||||
|
"receiverId": 1,
|
||||||
|
"receiverName": "Astsb. Cahit Demir",
|
||||||
|
"receiverRank": "Astsubay",
|
||||||
|
"receiverRegistry": "CD5561",
|
||||||
|
"receiverPhone": "+90 532 223 45 67",
|
||||||
|
"giverId": 2,
|
||||||
|
"giverName": "Sv. Uzm. Er Ali Korkmaz",
|
||||||
|
"giverRank": "Sozlesmeli Er",
|
||||||
|
"giverRegistry": "AK7812",
|
||||||
|
"giverPhone": "+90 555 893 22 10",
|
||||||
|
"notes": "Normal ikmal",
|
||||||
|
"inventoryManagerId": 3,
|
||||||
|
"inventoryManagerName": "Mal Sorumlusu 1",
|
||||||
|
"fuelManagerId": 2,
|
||||||
|
"status": "pending",
|
||||||
|
"rejectionReason": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### POST /fuel-slips
|
||||||
|
Yeni yakıt fişi oluşturur.
|
||||||
|
|
||||||
|
**Yetki:** Yakıt Sorumlusu
|
||||||
|
|
||||||
|
**İstek:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"date": "2024-01-01",
|
||||||
|
"force": "MSB",
|
||||||
|
"unitId": 1,
|
||||||
|
"vehicleId": 1,
|
||||||
|
"fuelAmountNumber": 50,
|
||||||
|
"fuelAmountText": "Elli",
|
||||||
|
"fuelType": "Benzin",
|
||||||
|
"receiverId": 1,
|
||||||
|
"giverId": 2,
|
||||||
|
"receiverPhone": "+90 532 223 45 67",
|
||||||
|
"giverPhone": "+90 555 893 22 10",
|
||||||
|
"notes": "Normal ikmal",
|
||||||
|
"inventoryManagerId": 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yanıt (201):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"slip": {
|
||||||
|
"id": 2,
|
||||||
|
"slipNumber": 2,
|
||||||
|
// ... diğer fiş bilgileri
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### GET /fuel-slips/:id/pdf
|
||||||
|
Yakıt fişini PDF formatında indirir.
|
||||||
|
|
||||||
|
**Yetki:** Yakıt Sorumlusu
|
||||||
|
|
||||||
|
**Yanıt (200)** - PDF dosyası
|
||||||
|
**Content-Type:** `application/pdf`
|
||||||
|
**Content-Disposition:** `inline; filename=akaryakit-senedi-0002.pdf`
|
||||||
|
|
||||||
|
## 📋 Mal Sorumlusu API
|
||||||
|
|
||||||
|
### GET /fuel-slips/assigned
|
||||||
|
Kullanıcıya atanan yakıt fişlerini listeler.
|
||||||
|
|
||||||
|
**Yetki:** Mal Sorumlusu
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"slips": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"slipNumber": 1,
|
||||||
|
"status": "pending",
|
||||||
|
// ... diğer fiş bilgileri
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### PATCH /fuel-slips/:id/status
|
||||||
|
Yakıt fişini onaylar veya reddeder.
|
||||||
|
|
||||||
|
**Yetki:** Mal Sorumlusu
|
||||||
|
|
||||||
|
**İstek (Onay):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "approved"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**İstek (Red):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "rejected",
|
||||||
|
"reason": "Araç bakımda olduğu için ikmal yapılamaz"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yanıt (200):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"slip": {
|
||||||
|
"id": 1,
|
||||||
|
"status": "approved",
|
||||||
|
"rejectionReason": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔌 WebSocket Olayları
|
||||||
|
|
||||||
|
### Bağlantı
|
||||||
|
```javascript
|
||||||
|
const socket = io('http://localhost:5005', {
|
||||||
|
auth: {
|
||||||
|
token: '<session-token>'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mal Sorumlusu Olayları
|
||||||
|
|
||||||
|
#### fuelSlip:new
|
||||||
|
Yeni yakıt fişi atandığında tetiklenir.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
socket.on('fuelSlip:new', (slip) => {
|
||||||
|
console.log('Yeni fiş:', slip);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### fuelSlip:status
|
||||||
|
Fiş durumu güncellendiğinde tetiklenir.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
socket.on('fuelSlip:status', (slip) => {
|
||||||
|
console.log('Fiş durumu güncellendi:', slip.status);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Yakıt Sorumlusu Olayları
|
||||||
|
|
||||||
|
#### fuelSlip:status
|
||||||
|
Fiş durumu güncellendiğinde tetiklenir.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
socket.on('fuelSlip:status', (slip) => {
|
||||||
|
console.log('Fiş durumu:', slip.status, 'Sebep:', slip.rejectionReason);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚠️ Hata Kodları
|
||||||
|
|
||||||
|
### HTTP Durum Kodları
|
||||||
|
- `200` - Başarılı
|
||||||
|
- `201` - Oluşturuldu
|
||||||
|
- `204` - İçerik Yok
|
||||||
|
- `400` - Geçersiz İstek
|
||||||
|
- `401` - Yetkisiz
|
||||||
|
- `403` - Yasak
|
||||||
|
- `404` - Bulunamadı
|
||||||
|
- `409` - Çakışma
|
||||||
|
- `500` - Sunucu Hatası
|
||||||
|
|
||||||
|
### Hata Mesajları
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Kullanici adi ve sifre zorunlu.",
|
||||||
|
"error": "Validation error"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Yaygın Hata Senaryoları
|
||||||
|
- **Session expired**: Token geçersiz veya süresi dolmuş
|
||||||
|
- **Insufficient permissions**: İstek için yetki yok
|
||||||
|
- **Resource not found**: İstenen kaynak bulunamadı
|
||||||
|
- **Validation failed**: Gerekli alanlar eksik veya geçersiz
|
||||||
|
- **Database constraint**: Veritabanı kısıtlaması ihlali
|
||||||
|
|
||||||
|
## 📝 Örnek Kod
|
||||||
|
|
||||||
|
### JavaScript/Node.js
|
||||||
|
```javascript
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
class YTPClient {
|
||||||
|
constructor(baseURL) {
|
||||||
|
this.client = axios.create({
|
||||||
|
baseURL,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async login(username, password) {
|
||||||
|
const response = await this.client.post('/auth/login', {
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
});
|
||||||
|
|
||||||
|
this.token = response.data.token;
|
||||||
|
this.client.defaults.headers['X-Session-Token'] = this.token;
|
||||||
|
|
||||||
|
return response.data.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
async createFuelSlip(slipData) {
|
||||||
|
const response = await this.client.post('/fuel-slips', slipData);
|
||||||
|
return response.data.slip;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFuelSlips() {
|
||||||
|
const response = await this.client.get('/fuel-slips');
|
||||||
|
return response.data.slips;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kullanım
|
||||||
|
const client = new YTPClient('http://localhost:5005/api');
|
||||||
|
await client.login('yakitsorum', 'Yakit@123');
|
||||||
|
const slips = await client.getFuelSlips();
|
||||||
|
```
|
||||||
|
|
||||||
|
### curl Örnekleri
|
||||||
|
```bash
|
||||||
|
# Giriş
|
||||||
|
curl -X POST http://localhost:5005/api/auth/login \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"username":"admin","password":"Admin!123"}'
|
||||||
|
|
||||||
|
# Yeni araç ekleme
|
||||||
|
curl -X POST http://localhost:5005/api/vehicles \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-Session-Token: YOUR_TOKEN" \
|
||||||
|
-d '{"brand":"Ford","model":"Transit","year":2021,"plate":"34 AYT 312"}'
|
||||||
|
|
||||||
|
# Yakıt fişlerini listeleme
|
||||||
|
curl -X GET http://localhost:5005/api/fuel-slips \
|
||||||
|
-H "X-Session-Token: YOUR_TOKEN"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Not**: Bu API dokümantasyonu geliştirme sürecinde güncellenebilir. Değişiklikler için release notlarını kontrol edin.
|
||||||
438
docs/DATABASE.md
Normal file
438
docs/DATABASE.md
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
# Veritabanı Şema Dokümantasyonu
|
||||||
|
|
||||||
|
Yakıt Takip Sistemi veritabanı yapısı, tablolar, ilişkiler ve veri modeli hakkında kapsamlı bilgi.
|
||||||
|
|
||||||
|
## 📋 İçerik
|
||||||
|
|
||||||
|
- [Genel Bakış](#genel-bakış)
|
||||||
|
- [Tablolar](#tablolar)
|
||||||
|
- [İlişkiler](#ilişkiler)
|
||||||
|
- [Veri Modeli](#veri-modeli)
|
||||||
|
- [Index'ler](#indexler)
|
||||||
|
- [Örnek Veriler](#örnek-veriler)
|
||||||
|
- [Migration](#migration)
|
||||||
|
|
||||||
|
## 🗄️ Genel Bakış
|
||||||
|
|
||||||
|
### Veritabanı Türü
|
||||||
|
- **Motor**: SQLite 3
|
||||||
|
- **Dosya**: `data/app.db`
|
||||||
|
- **Encoding**: UTF-8
|
||||||
|
- **Foreign Keys**: Aktif
|
||||||
|
|
||||||
|
### Tasarım İlkeleri
|
||||||
|
- Normalizasyon: 3NF
|
||||||
|
- Veri bütünlüğü: Foreign key constraints
|
||||||
|
- Audit trail: created_at timestamp'ları
|
||||||
|
- Atomic operations: Transaction destek
|
||||||
|
|
||||||
|
## 📊 Tablolar
|
||||||
|
|
||||||
|
### users
|
||||||
|
Sistem kullanıcılarını ve rollerini tutar.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username TEXT UNIQUE NOT NULL,
|
||||||
|
password TEXT NOT NULL,
|
||||||
|
role TEXT NOT NULL CHECK(role IN ('admin','fuel_manager','inventory_manager')),
|
||||||
|
display_name TEXT NOT NULL,
|
||||||
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
| Kolon | Tip | Kısıtlar | Açıklama |
|
||||||
|
|-------|-----|----------|----------|
|
||||||
|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Benzersiz kullanıcı ID |
|
||||||
|
| username | TEXT | UNIQUE, NOT NULL | Kullanıcı adı |
|
||||||
|
| password | TEXT | NOT NULL | Şifre (hash'lenmemiş) |
|
||||||
|
| role | TEXT | NOT NULL, CHECK | Kullanıcı rolü |
|
||||||
|
| display_name | TEXT | NOT NULL | Görünen ad |
|
||||||
|
| created_at | TEXT | DEFAULT CURRENT_TIMESTAMP | Kayıt tarihi |
|
||||||
|
|
||||||
|
### vehicles
|
||||||
|
Araç bilgilerini tutar.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE vehicles (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
brand TEXT NOT NULL,
|
||||||
|
model TEXT NOT NULL,
|
||||||
|
year INTEGER NOT NULL,
|
||||||
|
plate TEXT UNIQUE NOT NULL,
|
||||||
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
| Kolon | Tip | Kısıtlar | Açıklama |
|
||||||
|
|-------|-----|----------|----------|
|
||||||
|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Benzersiz araç ID |
|
||||||
|
| brand | TEXT | NOT NULL | Marka |
|
||||||
|
| model | TEXT | NOT NULL | Model |
|
||||||
|
| year | INTEGER | NOT NULL | Model yılı |
|
||||||
|
| plate | TEXT | UNIQUE, NOT NULL | Plaka |
|
||||||
|
| created_at | TEXT | DEFAULT CURRENT_TIMESTAMP | Kayıt tarihi |
|
||||||
|
|
||||||
|
### units
|
||||||
|
Askeri birlik bilgilerini tutar.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE units (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT UNIQUE NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
stk TEXT NOT NULL,
|
||||||
|
btk TEXT NOT NULL,
|
||||||
|
contact_name TEXT NOT NULL,
|
||||||
|
contact_rank TEXT NOT NULL,
|
||||||
|
contact_registry TEXT NOT NULL,
|
||||||
|
contact_identity TEXT NOT NULL,
|
||||||
|
contact_phone TEXT NOT NULL,
|
||||||
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
| Kolon | Tip | Kısıtlar | Açıklama |
|
||||||
|
|-------|-----|----------|----------|
|
||||||
|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Benzersiz birlik ID |
|
||||||
|
| name | TEXT | UNIQUE, NOT NULL | Birlik adı |
|
||||||
|
| address | TEXT | NOT NULL | Adres |
|
||||||
|
| stk | TEXT | NOT NULL | STK kodu |
|
||||||
|
| btk | TEXT | NOT NULL | BTK kodu |
|
||||||
|
| contact_name | TEXT | NOT NULL | Sorumlu kişi adı |
|
||||||
|
| contact_rank | TEXT | NOT NULL | Rütbe |
|
||||||
|
| contact_registry | TEXT | NOT NULL | Sicil no |
|
||||||
|
| contact_identity | TEXT | NOT NULL | TC kimlik no |
|
||||||
|
| contact_phone | TEXT | NOT NULL | Telefon |
|
||||||
|
| created_at | TEXT | DEFAULT CURRENT_TIMESTAMP | Kayıt tarihi |
|
||||||
|
|
||||||
|
### fuel_personnel
|
||||||
|
Yakıt personeli bilgilerini tutar.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE fuel_personnel (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
full_name TEXT NOT NULL,
|
||||||
|
rank TEXT NOT NULL,
|
||||||
|
registry_number TEXT UNIQUE NOT NULL,
|
||||||
|
identity_number TEXT NOT NULL,
|
||||||
|
phone TEXT NOT NULL,
|
||||||
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
| Kolon | Tip | Kısıtlar | Açıklama |
|
||||||
|
|-------|-----|----------|----------|
|
||||||
|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Benzersiz personel ID |
|
||||||
|
| full_name | TEXT | NOT NULL | Tam ad |
|
||||||
|
| rank | TEXT | NOT NULL | Rütbe |
|
||||||
|
| registry_number | TEXT | UNIQUE, NOT NULL | Sicil numarası |
|
||||||
|
| identity_number | TEXT | NOT NULL | TC kimlik no |
|
||||||
|
| phone | TEXT | NOT NULL | Telefon |
|
||||||
|
| created_at | TEXT | DEFAULT CURRENT_TIMESTAMP | Kayıt tarihi |
|
||||||
|
|
||||||
|
### fuel_slips
|
||||||
|
Yakıt ikmal fişlerini tutar.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE fuel_slips (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
slip_number INTEGER UNIQUE,
|
||||||
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
slip_date TEXT NOT NULL,
|
||||||
|
force TEXT NOT NULL,
|
||||||
|
unit_id INTEGER NOT NULL,
|
||||||
|
unit_name TEXT NOT NULL,
|
||||||
|
vehicle_id INTEGER NOT NULL,
|
||||||
|
vehicle_description TEXT NOT NULL,
|
||||||
|
plate TEXT NOT NULL,
|
||||||
|
fuel_amount_number REAL NOT NULL,
|
||||||
|
fuel_amount_text TEXT NOT NULL,
|
||||||
|
fuel_type TEXT NOT NULL,
|
||||||
|
receiver_id INTEGER NOT NULL,
|
||||||
|
receiver_name TEXT NOT NULL,
|
||||||
|
receiver_rank TEXT NOT NULL,
|
||||||
|
receiver_registry TEXT NOT NULL,
|
||||||
|
receiver_phone TEXT NOT NULL,
|
||||||
|
giver_id INTEGER NOT NULL,
|
||||||
|
giver_name TEXT NOT NULL,
|
||||||
|
giver_rank TEXT NOT NULL,
|
||||||
|
giver_registry TEXT NOT NULL,
|
||||||
|
giver_phone TEXT NOT NULL,
|
||||||
|
notes TEXT,
|
||||||
|
inventory_manager_id INTEGER NOT NULL,
|
||||||
|
fuel_manager_id INTEGER NOT NULL,
|
||||||
|
status TEXT DEFAULT 'pending',
|
||||||
|
rejection_reason TEXT,
|
||||||
|
FOREIGN KEY (unit_id) REFERENCES units(id),
|
||||||
|
FOREIGN KEY (vehicle_id) REFERENCES vehicles(id),
|
||||||
|
FOREIGN KEY (receiver_id) REFERENCES fuel_personnel(id),
|
||||||
|
FOREIGN KEY (giver_id) REFERENCES fuel_personnel(id),
|
||||||
|
FOREIGN KEY (inventory_manager_id) REFERENCES users(id),
|
||||||
|
FOREIGN KEY (fuel_manager_id) REFERENCES users(id)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
| Kolon | Tip | Kısıtlar | Açıklama |
|
||||||
|
|-------|-----|----------|----------|
|
||||||
|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Benzersiz fiş ID |
|
||||||
|
| slip_number | INTEGER | UNIQUE | Fiş seri numarası |
|
||||||
|
| created_at | TEXT | DEFAULT CURRENT_TIMESTAMP | Oluşturma tarihi |
|
||||||
|
| slip_date | TEXT | NOT NULL | Fiş tarihi |
|
||||||
|
| force | TEXT | NOT NULL | Kuvvet (MSB, KKK, etc.) |
|
||||||
|
| unit_id | INTEGER | FOREIGN KEY, NOT NULL | Birlik ID |
|
||||||
|
| unit_name | TEXT | NOT NULL | Birlik adı (redunant) |
|
||||||
|
| vehicle_id | INTEGER | FOREIGN KEY, NOT NULL | Araç ID |
|
||||||
|
| vehicle_description | TEXT | NOT NULL | Araç açıklaması |
|
||||||
|
| plate | TEXT | NOT NULL | Plaka |
|
||||||
|
| fuel_amount_number | REAL | NOT NULL | Yakıt miktarı (rakam) |
|
||||||
|
| fuel_amount_text | TEXT | NOT NULL | Yakıt miktarı (yazı) |
|
||||||
|
| fuel_type | TEXT | NOT NULL | Yakıt türü |
|
||||||
|
| receiver_id | INTEGER | FOREIGN KEY, NOT NULL | Teslim alan ID |
|
||||||
|
| receiver_name | TEXT | NOT NULL | Teslim alan adı |
|
||||||
|
| receiver_rank | TEXT | NOT NULL | Teslim alan rütbesi |
|
||||||
|
| receiver_registry | TEXT | NOT NULL | Teslim alan sicili |
|
||||||
|
| receiver_phone | TEXT | NOT NULL | Teslim alan telefonu |
|
||||||
|
| giver_id | INTEGER | FOREIGN KEY, NOT NULL | Teslim eden ID |
|
||||||
|
| giver_name | TEXT | NOT NULL | Teslim eden adı |
|
||||||
|
| giver_rank | TEXT | NOT NULL | Teslim eden rütbesi |
|
||||||
|
| giver_registry | TEXT | NOT NULL | Teslim eden sicili |
|
||||||
|
| giver_phone | TEXT | NOT NULL | Teslim eden telefonu |
|
||||||
|
| notes | TEXT | NULL | Notlar |
|
||||||
|
| inventory_manager_id | INTEGER | FOREIGN KEY, NOT NULL | Mal sorumlusu ID |
|
||||||
|
| fuel_manager_id | INTEGER | FOREIGN KEY, NOT NULL | Yakıt sorumlusu ID |
|
||||||
|
| status | TEXT | DEFAULT 'pending' | Durum (pending/approved/rejected) |
|
||||||
|
| rejection_reason | TEXT | NULL | Red gerekçesi |
|
||||||
|
|
||||||
|
## 🔗 İlişkiler
|
||||||
|
|
||||||
|
### Entity Relationship Diagram
|
||||||
|
```
|
||||||
|
users (1) -----> (0..n) fuel_slips (fuel_manager_id)
|
||||||
|
users (1) -----> (0..n) fuel_slips (inventory_manager_id)
|
||||||
|
users (1) -----> (0..n) users (admin creates)
|
||||||
|
|
||||||
|
units (1) -----> (0..n) fuel_slips (unit_id)
|
||||||
|
|
||||||
|
vehicles (1) -----> (0..n) fuel_slips (vehicle_id)
|
||||||
|
|
||||||
|
fuel_personnel (1) -----> (0..n) fuel_slips (receiver_id)
|
||||||
|
fuel_personnel (1) -----> (0..n) fuel_slips (giver_id)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Relationship Types
|
||||||
|
- **One-to-Many**: users → fuel_slips (hem fuel_manager_id hem de inventory_manager_id)
|
||||||
|
- **One-to-Many**: units → fuel_slips
|
||||||
|
- **One-to-Many**: vehicles → fuel_slips
|
||||||
|
- **One-to-Many**: fuel_personnel → fuel_slips (hem receiver_id hem de giver_id)
|
||||||
|
|
||||||
|
## 📈 Veri Modeli
|
||||||
|
|
||||||
|
### Status Flow (fuel_slips.status)
|
||||||
|
```
|
||||||
|
pending → approved
|
||||||
|
↓
|
||||||
|
rejected
|
||||||
|
```
|
||||||
|
|
||||||
|
### Role Hierarchy
|
||||||
|
```
|
||||||
|
admin (süper kullanıcı)
|
||||||
|
├── fuel_manager (fiş oluşturabilir)
|
||||||
|
└── inventory_manager (fiş onaylayabilir)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kuvvet Listesi (Enum)
|
||||||
|
```sql
|
||||||
|
-- Geçerli kuvvet değerleri
|
||||||
|
'MSB', 'K.K.K.', 'Dz.K.K.', 'Hv.K.K.', 'SGK', 'Gnkur. Bşk.', 'Hrt.Gn.K.'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Yakıt Türleri (Örnek)
|
||||||
|
```sql
|
||||||
|
-- Örnek yakıt türleri
|
||||||
|
'Benzin', 'Motorin', 'Benzin-95', 'Motorin-10', 'LPG'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🗂️ Index'ler
|
||||||
|
|
||||||
|
### Otomatik Index'ler
|
||||||
|
- `PRIMARY KEY` → Her tabloda otomatik oluşturulur
|
||||||
|
- `UNIQUE` → Belirtilen kolonlarda otomatik oluşturulur
|
||||||
|
|
||||||
|
### Önerilen Manuel Index'ler
|
||||||
|
```sql
|
||||||
|
-- Performans için önerilen index'ler
|
||||||
|
CREATE INDEX idx_fuel_slips_status ON fuel_slips(status);
|
||||||
|
CREATE INDEX idx_fuel_slips_date ON fuel_slips(slip_date);
|
||||||
|
CREATE INDEX idx_fuel_slips_inventory_manager ON fuel_slips(inventory_manager_id);
|
||||||
|
CREATE INDEX idx_fuel_slips_fuel_manager ON fuel_slips(fuel_manager_id);
|
||||||
|
CREATE INDEX idx_vehicles_plate ON vehicles(plate);
|
||||||
|
CREATE INDEX idx_units_name ON units(name);
|
||||||
|
CREATE INDEX idx_users_role ON users(role);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Örnek Veriler
|
||||||
|
|
||||||
|
### users Tablosu
|
||||||
|
```sql
|
||||||
|
INSERT INTO users (username, password, role, display_name) VALUES
|
||||||
|
('admin', 'Admin!123', 'admin', 'Istasyon Admini'),
|
||||||
|
('yakitsorum', 'Yakit@123', 'fuel_manager', 'Yakit Sorumlusu'),
|
||||||
|
('malsorum1', 'Mal@123', 'inventory_manager', 'Mal Sorumlusu 1');
|
||||||
|
```
|
||||||
|
|
||||||
|
### vehicles Tablosu
|
||||||
|
```sql
|
||||||
|
INSERT INTO vehicles (brand, model, year, plate) VALUES
|
||||||
|
('Ford', 'Transit', 2021, '34 AYT 312'),
|
||||||
|
('Isuzu', 'NPR', 2019, '34 FZT 908');
|
||||||
|
```
|
||||||
|
|
||||||
|
### units Tablosu
|
||||||
|
```sql
|
||||||
|
INSERT INTO units (
|
||||||
|
name, address, stk, btk, contact_name, contact_rank,
|
||||||
|
contact_registry, contact_identity, contact_phone
|
||||||
|
) VALUES
|
||||||
|
(
|
||||||
|
'Merkez Birlik',
|
||||||
|
'Cumhuriyet Mah. İstasyon Cad. No:12/1 İstanbul',
|
||||||
|
'STK-4589',
|
||||||
|
'BTK-9021',
|
||||||
|
'Yzb. Murat Kaya',
|
||||||
|
'Yuzbasi',
|
||||||
|
'MK4587',
|
||||||
|
'25478963210',
|
||||||
|
'+90 532 456 78 12'
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### fuel_personnel Tablosu
|
||||||
|
```sql
|
||||||
|
INSERT INTO fuel_personnel (
|
||||||
|
full_name, rank, registry_number, identity_number, phone
|
||||||
|
) VALUES
|
||||||
|
(
|
||||||
|
'Astsb. Cahit Demir',
|
||||||
|
'Astsubay',
|
||||||
|
'CD5561',
|
||||||
|
'14523698741',
|
||||||
|
'+90 532 223 45 67'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'Sv. Uzm. Er Ali Korkmaz',
|
||||||
|
'Sozlesmeli Er',
|
||||||
|
'AK7812',
|
||||||
|
'32987456100',
|
||||||
|
'+90 555 893 22 10'
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### fuel_slips Tablosu
|
||||||
|
```sql
|
||||||
|
INSERT INTO fuel_slips (
|
||||||
|
slip_number, slip_date, force, unit_id, unit_name,
|
||||||
|
vehicle_id, vehicle_description, plate,
|
||||||
|
fuel_amount_number, fuel_amount_text, fuel_type,
|
||||||
|
receiver_id, receiver_name, receiver_rank, receiver_registry, receiver_phone,
|
||||||
|
giver_id, giver_name, giver_rank, giver_registry, giver_phone,
|
||||||
|
inventory_manager_id, fuel_manager_id
|
||||||
|
) VALUES
|
||||||
|
(
|
||||||
|
1, '2024-01-01', 'MSB', 1, 'Merkez Birlik',
|
||||||
|
1, 'Ford Transit', '34 AYT 312',
|
||||||
|
50, 'Elli', 'Benzin',
|
||||||
|
1, 'Astsb. Cahit Demir', 'Astsubay', 'CD5561', '+90 532 223 45 67',
|
||||||
|
2, 'Sv. Uzm. Er Ali Korkmaz', 'Sozlesmeli Er', 'AK7812', '+90 555 893 22 10',
|
||||||
|
3, 2
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Migration
|
||||||
|
|
||||||
|
### Sürüm Geçmişi
|
||||||
|
|
||||||
|
#### v1.0.0 - İlk Sürüm
|
||||||
|
- users, vehicles, units, fuel_personnel, fuel_slips tabloları oluşturuldu
|
||||||
|
- Temel foreign key ilişkileri kuruldu
|
||||||
|
- Örnek veriler eklendi
|
||||||
|
|
||||||
|
#### v1.1.0 - Status Eklendi
|
||||||
|
- `fuel_slips` tablosuna `status` kolonu eklendi
|
||||||
|
- `fuel_slips` tablosuna `rejection_reason` kolonu eklendi
|
||||||
|
- Mevcut kayıtlar için 'pending' olarak varsayılan değer atandı
|
||||||
|
|
||||||
|
### Migration Script'i
|
||||||
|
```sql
|
||||||
|
-- v1.1.0 Migration
|
||||||
|
ALTER TABLE fuel_slips ADD COLUMN status TEXT DEFAULT 'pending';
|
||||||
|
ALTER TABLE fuel_slips ADD COLUMN rejection_reason TEXT;
|
||||||
|
|
||||||
|
-- Örnek index'ler
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_fuel_slips_status ON fuel_slips(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_fuel_slips_date ON fuel_slips(slip_date);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_fuel_slips_inventory_manager ON fuel_slips(inventory_manager_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Veritabanı Yedekleme
|
||||||
|
```bash
|
||||||
|
# SQLite yedekleme
|
||||||
|
sqlite3 data/app.db ".backup data/app_backup_$(date +%Y%m%d_%H%M%S).db"
|
||||||
|
|
||||||
|
# Veri dışa aktarma
|
||||||
|
sqlite3 data/app.db ".dump" > data/app_export_$(date +%Y%m%d_%H%M%S).sql
|
||||||
|
|
||||||
|
# Veri içe aktarma
|
||||||
|
sqlite3 data/app.db < data/app_export_20240101_120000.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Veri Sorguları
|
||||||
|
|
||||||
|
### Yaygın Sorgular
|
||||||
|
|
||||||
|
#### Aktif Kullanıcılar
|
||||||
|
```sql
|
||||||
|
SELECT role, COUNT(*) as count FROM users GROUP BY role;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Aylık Yakıt İstatistikleri
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
strftime('%Y-%m', slip_date) as month,
|
||||||
|
COUNT(*) as slip_count,
|
||||||
|
SUM(fuel_amount_number) as total_fuel
|
||||||
|
FROM fuel_slips
|
||||||
|
WHERE status = 'approved'
|
||||||
|
GROUP BY strftime('%Y-%m', slip_date)
|
||||||
|
ORDER BY month DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Birlik Bazında İstatistikler
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
u.name,
|
||||||
|
COUNT(fs.id) as slip_count,
|
||||||
|
SUM(fs.fuel_amount_number) as total_fuel
|
||||||
|
FROM units u
|
||||||
|
LEFT JOIN fuel_slips fs ON u.id = fs.unit_id AND fs.status = 'approved'
|
||||||
|
GROUP BY u.id, u.name
|
||||||
|
ORDER BY slip_count DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Personel Aktivitesi
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
fp.full_name,
|
||||||
|
fp.rank,
|
||||||
|
COUNT(CASE WHEN fs.id IS NOT NULL THEN 1 END) as slips_involved
|
||||||
|
FROM fuel_personnel fp
|
||||||
|
LEFT JOIN fuel_slips fs ON fp.id = fs.receiver_id OR fp.id = fs.giver_id
|
||||||
|
GROUP BY fp.id, fp.full_name, fp.rank
|
||||||
|
ORDER BY slips_involved DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Not**: Veritabanı yapısı geliştirme sürecinde değişebilir. Migration geçmişini takip etmek önemlidir.
|
||||||
729
docs/DEPLOYMENT.md
Normal file
729
docs/DEPLOYMENT.md
Normal file
@@ -0,0 +1,729 @@
|
|||||||
|
# Geliştirme ve Dağıtım Kılavuzu
|
||||||
|
|
||||||
|
Yakıt Takip Sistemi geliştirme ortamı kurulumu, test süreçleri ve prodüksiyon dağıtımı hakkında kapsamlı rehber.
|
||||||
|
|
||||||
|
## 📋 İçerlik
|
||||||
|
|
||||||
|
- [Geliştirme Ortamı Kurulumu](#geliştirme-ortamı-kurulumu)
|
||||||
|
- [Geliştirme Süreci](#geliştirme-süreci)
|
||||||
|
- [Test Stratejisi](#test-stratejisi)
|
||||||
|
- [Prodüksiyon Dağıtımı](#prodüksiyon-dağıtımı)
|
||||||
|
- [İzleme ve Bakım](#izleme-ve-bakım)
|
||||||
|
- [Sorun Giderme](#sorun-giderme)
|
||||||
|
|
||||||
|
## 🛠️ Geliştirme Ortamı Kurulumu
|
||||||
|
|
||||||
|
### Gereksinimler
|
||||||
|
- **Node.js**: 16.x veya üzeri
|
||||||
|
- **npm**: 7.x veya üzeri
|
||||||
|
- **Git**: Son sürüm
|
||||||
|
- **Editör**: VS Code (önerilen)
|
||||||
|
- **Tarayıcı**: Chrome/Firefox (geliştirme araçları)
|
||||||
|
|
||||||
|
### Adım 1: Sistemi Kurun
|
||||||
|
|
||||||
|
#### Node.js Kurulumu
|
||||||
|
```bash
|
||||||
|
# macOS (Homebrew)
|
||||||
|
brew install node
|
||||||
|
|
||||||
|
# Ubuntu/Debian
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||||
|
sudo apt-get install -y nodejs
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
# https://nodejs.org/en/download/ adresinden indirin
|
||||||
|
```
|
||||||
|
|
||||||
|
#### VS Code ve Eklentiler
|
||||||
|
```bash
|
||||||
|
# Önerilen VS Code eklentileri
|
||||||
|
- Svelte for VS Code
|
||||||
|
- SQLite
|
||||||
|
- Thunder Client (API testing)
|
||||||
|
- GitLens
|
||||||
|
- Prettier
|
||||||
|
- ESLint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 2: Projeyi Kurun
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Repoyu klonlayın
|
||||||
|
git clone <repository-url>
|
||||||
|
cd ytp
|
||||||
|
|
||||||
|
# 2. Ana proje bağımlılıklarını yükleyin
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 3. Frontend bağımlılıklarını yükleyin
|
||||||
|
cd client
|
||||||
|
npm install
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# 4. Veritabanını başlatın
|
||||||
|
npm run prepare:db
|
||||||
|
|
||||||
|
# 5. Ortam değişkenlerini yapılandırın
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 3: Ortam Değişkenleri
|
||||||
|
|
||||||
|
#### .env Dosyası
|
||||||
|
```bash
|
||||||
|
# Sunucu ayarları
|
||||||
|
PORT=5005
|
||||||
|
NODE_ENV=development
|
||||||
|
|
||||||
|
# Veritabanı ayarları
|
||||||
|
DB_PATH=./data/app.db
|
||||||
|
|
||||||
|
# Session ayarları
|
||||||
|
SESSION_SECRET=your-secret-key-here
|
||||||
|
SESSION_TIMEOUT=24h
|
||||||
|
|
||||||
|
# CORS ayarları
|
||||||
|
CORS_ORIGIN=http://localhost:5173
|
||||||
|
|
||||||
|
# Log seviyesi
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 4: Geliştirme Sunucusunu Başlatın
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Geliştirme modunda başlatma (hem backend hem frontend)
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Sadece backend sunucusu
|
||||||
|
npm run start:server
|
||||||
|
|
||||||
|
# Sadece frontend (ayrı terminal)
|
||||||
|
cd client && npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adım 5: Doğrulama
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Sunucu çalışıyor mu?
|
||||||
|
curl http://localhost:5005/api/session
|
||||||
|
|
||||||
|
# Frontend çalışıyor mu?
|
||||||
|
# Tarayıcıda http://localhost:5173 açın
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Geliştirme Süreci
|
||||||
|
|
||||||
|
### Git Workflow
|
||||||
|
|
||||||
|
#### Branch Stratejisi
|
||||||
|
```
|
||||||
|
main # Prodüksiyon branch'i
|
||||||
|
├── develop # Geliştirme branch'i
|
||||||
|
├── feature/* # Yeni özellikler
|
||||||
|
├── bugfix/* # Hata düzeltmeleri
|
||||||
|
└── hotfix/* # Acil düzeltmeler
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Commit Mesajları
|
||||||
|
```bash
|
||||||
|
# Format
|
||||||
|
<type>(<scope>): <description>
|
||||||
|
|
||||||
|
# Örnekler
|
||||||
|
feat(auth): add JWT token refresh mechanism
|
||||||
|
fix(api): handle null vehicle_id gracefully
|
||||||
|
docs(readme): update installation instructions
|
||||||
|
refactor(db): optimize fuel_slip queries
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Geliştirme Akışı
|
||||||
|
```bash
|
||||||
|
# 1. Yeni feature branch oluştur
|
||||||
|
git checkout -b feature/fuel-slip-pdf
|
||||||
|
|
||||||
|
# 2. Geliştirme yap
|
||||||
|
# ... kod değişiklikleri
|
||||||
|
|
||||||
|
# 3. Değişiklikleri commit et
|
||||||
|
git add .
|
||||||
|
git commit -m "feat(fuel): add PDF generation for fuel slips"
|
||||||
|
|
||||||
|
# 4. Branch'e push et
|
||||||
|
git push origin feature/fuel-slip-pdf
|
||||||
|
|
||||||
|
# 5. Pull Request oluştur
|
||||||
|
# GitHub/GitLab üzerinden PR oluştur
|
||||||
|
|
||||||
|
# 6. Review ve merge
|
||||||
|
# Code review sonrası develop branch'ine merge
|
||||||
|
|
||||||
|
# 7. Geliştirme sunucusunu güncelle
|
||||||
|
git checkout develop
|
||||||
|
git pull origin develop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kod Kalitesi
|
||||||
|
|
||||||
|
#### ESLint Yapılandırması
|
||||||
|
```json
|
||||||
|
// .eslintrc.json
|
||||||
|
{
|
||||||
|
"extends": ["eslint:recommended"],
|
||||||
|
"env": {
|
||||||
|
"node": true,
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-console": "warn",
|
||||||
|
"no-unused-vars": "error",
|
||||||
|
"prefer-const": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Prettier Yapılandırması
|
||||||
|
```json
|
||||||
|
// .prettierrc
|
||||||
|
{
|
||||||
|
"semi": true,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 80,
|
||||||
|
"tabWidth": 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Stratejisi
|
||||||
|
|
||||||
|
#### Test Türleri
|
||||||
|
- **Unit Tests**: Fonksiyon ve bileşen testleri
|
||||||
|
- **Integration Tests**: API endpoint testleri
|
||||||
|
- **E2E Tests**: Kullanıcı senaryoları
|
||||||
|
- **Manual Tests**: Manuel QA süreçleri
|
||||||
|
|
||||||
|
#### Test Tools
|
||||||
|
```bash
|
||||||
|
# Test framework'leri
|
||||||
|
npm install --save-dev jest supertest
|
||||||
|
npm install --save-dev @testing-library/svelte
|
||||||
|
npm install --save-dev playwright
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Örnek Testler
|
||||||
|
```javascript
|
||||||
|
// tests/api.test.js
|
||||||
|
const request = require('supertest');
|
||||||
|
const app = require('../server/index');
|
||||||
|
|
||||||
|
describe('Authentication', () => {
|
||||||
|
test('POST /api/auth/login with valid credentials', async () => {
|
||||||
|
const response = await request(app)
|
||||||
|
.post('/api/auth/login')
|
||||||
|
.send({ username: 'admin', password: 'Admin!123' })
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
expect(response.body).toHaveProperty('token');
|
||||||
|
expect(response.body.user.role).toBe('admin');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Prodüksiyon Dağıtımı
|
||||||
|
|
||||||
|
### Dağıtım Seçenekleri
|
||||||
|
|
||||||
|
#### 1. Docker Dağıtımı (Önerilen)
|
||||||
|
|
||||||
|
##### Dockerfile
|
||||||
|
```dockerfile
|
||||||
|
# Multi-stage build
|
||||||
|
FROM node:18-alpine AS builder
|
||||||
|
|
||||||
|
# Build stage
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci --only=production
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
WORKDIR /app/client
|
||||||
|
RUN npm ci
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM node:18-alpine AS production
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/package*.json ./
|
||||||
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
|
COPY --from=builder /app/server ./server
|
||||||
|
COPY --from=builder /app/client/dist ./client/dist
|
||||||
|
COPY --from=builder /app/data ./data
|
||||||
|
|
||||||
|
EXPOSE 5005
|
||||||
|
|
||||||
|
CMD ["node", "server/index.js"]
|
||||||
|
```
|
||||||
|
|
||||||
|
##### docker-compose.yml
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
ytp-app:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "5005:5005"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=5005
|
||||||
|
volumes:
|
||||||
|
- ./data:/app/data
|
||||||
|
- ./logs:/app/logs
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||||
|
- ./ssl:/etc/nginx/ssl
|
||||||
|
depends_on:
|
||||||
|
- ytp-app
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Docker Komutları
|
||||||
|
```bash
|
||||||
|
# Build ve çalıştırma
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# Logları izleme
|
||||||
|
docker-compose logs -f ytp-app
|
||||||
|
|
||||||
|
# Yeniden başlatma
|
||||||
|
docker-compose restart ytp-app
|
||||||
|
|
||||||
|
# Temizleme
|
||||||
|
docker-compose down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. PM2 ile Dağıtım
|
||||||
|
|
||||||
|
##### PM2 Yapılandırması
|
||||||
|
```json
|
||||||
|
// ecosystem.config.js
|
||||||
|
module.exports = {
|
||||||
|
apps: [{
|
||||||
|
name: 'ytp-app',
|
||||||
|
script: 'server/index.js',
|
||||||
|
instances: 'max',
|
||||||
|
exec_mode: 'cluster',
|
||||||
|
env: {
|
||||||
|
NODE_ENV: 'production',
|
||||||
|
PORT: 5005
|
||||||
|
},
|
||||||
|
error_file: './logs/err.log',
|
||||||
|
out_file: './logs/out.log',
|
||||||
|
log_file: './logs/combined.log',
|
||||||
|
time: true
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### PM2 Komutları
|
||||||
|
```bash
|
||||||
|
# PM2 kurulumu
|
||||||
|
npm install -g pm2
|
||||||
|
|
||||||
|
# Uygulamayı başlatma
|
||||||
|
pm2 start ecosystem.config.js
|
||||||
|
|
||||||
|
# Durumunu kontrol etme
|
||||||
|
pm2 status
|
||||||
|
|
||||||
|
# Logları izleme
|
||||||
|
pm2 logs ytp-app
|
||||||
|
|
||||||
|
# Yeniden başlatma
|
||||||
|
pm2 restart ytp-app
|
||||||
|
|
||||||
|
# Sunucu yeniden başlatığında otomatik başlatma
|
||||||
|
pm2 startup
|
||||||
|
pm2 save
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Systemd Service
|
||||||
|
|
||||||
|
##### Service Dosyası
|
||||||
|
```ini
|
||||||
|
# /etc/systemd/system/ytp.service
|
||||||
|
[Unit]
|
||||||
|
Description=Yakit Takip Sistemi
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=www-data
|
||||||
|
WorkingDirectory=/var/www/ytp
|
||||||
|
ExecStart=/usr/bin/node server/index.js
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
Environment=PORT=5005
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Systemd Komutları
|
||||||
|
```bash
|
||||||
|
# Service'i etkinleştirme
|
||||||
|
sudo systemctl enable ytp.service
|
||||||
|
|
||||||
|
# Service'i başlatma
|
||||||
|
sudo systemctl start ytp.service
|
||||||
|
|
||||||
|
# Durumunu kontrol etme
|
||||||
|
sudo systemctl status ytp.service
|
||||||
|
|
||||||
|
# Logları izleme
|
||||||
|
sudo journalctl -u ytp.service -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nginx Yapılandırması
|
||||||
|
|
||||||
|
#### nginx.conf
|
||||||
|
```nginx
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
upstream ytp_backend {
|
||||||
|
server 127.0.0.1:5005;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name your-domain.com;
|
||||||
|
|
||||||
|
# Frontend statik dosyaları
|
||||||
|
location / {
|
||||||
|
root /var/www/ytp/client/dist;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
|
||||||
|
# Cache headers
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# API requests
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://ytp_backend;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# WebSocket connections
|
||||||
|
location /socket.io/ {
|
||||||
|
proxy_pass http://ytp_backend;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTPS (SSL kuruluysa)
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name your-domain.com;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/key.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
# Aynı proxy ayarları burada da geçerli
|
||||||
|
# ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prodüksiyon Kurulum Script'i
|
||||||
|
|
||||||
|
#### setup.sh
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Prodüksiyon kurulum script'i
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🚀 YTP Prodüksiyon Kurulumu Başlatılıyor..."
|
||||||
|
|
||||||
|
# Sistem güncellemeleri
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Node.js kurulumu
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||||
|
sudo apt-get install -y nodejs
|
||||||
|
|
||||||
|
# PM2 kurulumu
|
||||||
|
sudo npm install -g pm2
|
||||||
|
|
||||||
|
# Nginx kurulumu
|
||||||
|
sudo apt install -y nginx
|
||||||
|
|
||||||
|
# Firewall ayarları
|
||||||
|
sudo ufw allow ssh
|
||||||
|
sudo ufw allow 'Nginx Full'
|
||||||
|
sudo ufw --force enable
|
||||||
|
|
||||||
|
# Proje kurulumu
|
||||||
|
sudo mkdir -p /var/www/ytp
|
||||||
|
sudo chown $USER:$USER /var/www/ytp
|
||||||
|
|
||||||
|
# Git ile projeyi çek
|
||||||
|
cd /var/www/ytp
|
||||||
|
git clone <repository-url> .
|
||||||
|
|
||||||
|
# Bağımlılıkları yükle
|
||||||
|
npm install
|
||||||
|
cd client && npm install && cd ..
|
||||||
|
|
||||||
|
# Veritabanını başlat
|
||||||
|
npm run prepare:db
|
||||||
|
|
||||||
|
# PM2 başlat
|
||||||
|
pm2 start ecosystem.config.js
|
||||||
|
pm2 startup
|
||||||
|
pm2 save
|
||||||
|
|
||||||
|
# Nginx yapılandırması
|
||||||
|
sudo cp nginx.conf /etc/nginx/sites-available/ytp
|
||||||
|
sudo ln -s /etc/nginx/sites-available/ytp /etc/nginx/sites-enabled/
|
||||||
|
sudo nginx -t && sudo systemctl reload nginx
|
||||||
|
|
||||||
|
echo "✅ Kurulum tamamlandı!"
|
||||||
|
echo "🌐 Uygulama: http://your-domain.com"
|
||||||
|
echo "📊 PM2 durumu: pm2 status"
|
||||||
|
echo "📋 Loglar: pm2 logs ytp-app"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 İzleme ve Bakım
|
||||||
|
|
||||||
|
### Log Yönetimi
|
||||||
|
|
||||||
|
#### Log Yapılandırması
|
||||||
|
```javascript
|
||||||
|
// server/logger.js
|
||||||
|
const winston = require('winston');
|
||||||
|
|
||||||
|
const logger = winston.createLogger({
|
||||||
|
level: process.env.LOG_LEVEL || 'info',
|
||||||
|
format: winston.format.combine(
|
||||||
|
winston.format.timestamp(),
|
||||||
|
winston.format.json()
|
||||||
|
),
|
||||||
|
transports: [
|
||||||
|
new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
|
||||||
|
new winston.transports.File({ filename: 'logs/combined.log' }),
|
||||||
|
new winston.transports.Console({
|
||||||
|
format: winston.format.simple()
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = logger;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Log Rotasyon
|
||||||
|
```bash
|
||||||
|
# logrotate yapılandırması
|
||||||
|
# /etc/logrotate.d/ytp
|
||||||
|
/var/www/ytp/logs/*.log {
|
||||||
|
daily
|
||||||
|
missingok
|
||||||
|
rotate 52
|
||||||
|
compress
|
||||||
|
notifempty
|
||||||
|
create 644 www-data www-data
|
||||||
|
postrotate
|
||||||
|
pm2 reloadLogs
|
||||||
|
endscript
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performans İzleme
|
||||||
|
|
||||||
|
#### Metrics Collection
|
||||||
|
```javascript
|
||||||
|
// server/metrics.js
|
||||||
|
const express = require('express');
|
||||||
|
const responseTime = require('response-time');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
// Response time middleware
|
||||||
|
app.use(responseTime((req, res, time) => {
|
||||||
|
console.log(`${req.method} ${req.url} - ${time}ms`);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Health check endpoint
|
||||||
|
app.get('/health', (req, res) => {
|
||||||
|
res.json({
|
||||||
|
status: 'healthy',
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
uptime: process.uptime(),
|
||||||
|
memory: process.memoryUsage()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup Stratejisi
|
||||||
|
|
||||||
|
#### Database Backup Script
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# backup.sh
|
||||||
|
|
||||||
|
BACKUP_DIR="/var/backups/ytp"
|
||||||
|
DATE=$(date +%Y%m%d_%H%M%S)
|
||||||
|
DB_PATH="/var/www/ytp/data/app.db"
|
||||||
|
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
|
||||||
|
# Veritabanı yedeği
|
||||||
|
sqlite3 $DB_PATH ".backup $BACKUP_DIR/app_backup_$DATE.db"
|
||||||
|
|
||||||
|
# Eski yedekleri temizle (30 gün)
|
||||||
|
find $BACKUP_DIR -name "app_backup_*.db" -mtime +30 -delete
|
||||||
|
|
||||||
|
echo "Backup completed: $BACKUP_DIR/app_backup_$DATE.db"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Cron Job
|
||||||
|
```bash
|
||||||
|
# Günlük backup (saat 02:00)
|
||||||
|
0 2 * * * /var/www/ytp/scripts/backup.sh
|
||||||
|
|
||||||
|
# Log rotation (haftalık)
|
||||||
|
0 3 * * 0 /usr/sbin/logrotate /etc/logrotate.d/ytp
|
||||||
|
|
||||||
|
# Sistem health check (5 dakikada bir)
|
||||||
|
*/5 * * * * curl -f http://localhost:5005/health || echo "Health check failed" | mail -s "YTP Alert" admin@domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Sorun Giderme
|
||||||
|
|
||||||
|
### Yaygın Sorunlar
|
||||||
|
|
||||||
|
#### 1. Port Çakışması
|
||||||
|
```bash
|
||||||
|
# Port kullanan süreci bul
|
||||||
|
lsof -i :5005
|
||||||
|
|
||||||
|
# Süreci sonlandır
|
||||||
|
kill -9 <PID>
|
||||||
|
|
||||||
|
# Farklı port kullan
|
||||||
|
PORT=3000 npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Veritabanı Hataları
|
||||||
|
```bash
|
||||||
|
# Veritabanı dosyası izinleri
|
||||||
|
sudo chown www-data:www-data data/app.db
|
||||||
|
sudo chmod 664 data/app.db
|
||||||
|
|
||||||
|
# Veritabanı durumu
|
||||||
|
sqlite3 data/app.db ".tables"
|
||||||
|
sqlite3 data/app.db "SELECT COUNT(*) FROM fuel_slips;"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Memory Issues
|
||||||
|
```bash
|
||||||
|
# Memory kullanımı
|
||||||
|
free -h
|
||||||
|
ps aux --sort=-%mem | head
|
||||||
|
|
||||||
|
# Node.js memory limit
|
||||||
|
node --max-old-space-size=4096 server/index.js
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Socket.IO Connection Issues
|
||||||
|
```bash
|
||||||
|
# WebSocket connection test
|
||||||
|
wscat -c ws://localhost:5005/socket.io/?EIO=4&transport=websocket
|
||||||
|
|
||||||
|
# Nginx log kontrolü
|
||||||
|
sudo tail -f /var/log/nginx/error.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debugging Tools
|
||||||
|
|
||||||
|
#### Node.js Debugging
|
||||||
|
```bash
|
||||||
|
# Debug mode
|
||||||
|
node --inspect server/index.js
|
||||||
|
|
||||||
|
# Chrome DevTools ile debugging
|
||||||
|
# chrome://inspect adresini açın
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Network Debugging
|
||||||
|
```bash
|
||||||
|
# Port test
|
||||||
|
telnet localhost 5005
|
||||||
|
|
||||||
|
# SSL cert test
|
||||||
|
openssl s_client -connect your-domain.com:443
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Optimization
|
||||||
|
|
||||||
|
#### Database Optimization
|
||||||
|
```sql
|
||||||
|
-- Index ekleme
|
||||||
|
CREATE INDEX idx_fuel_slips_date ON fuel_slips(slip_date);
|
||||||
|
CREATE INDEX idx_fuel_slips_status ON fuel_slips(status);
|
||||||
|
|
||||||
|
-- Query optimization
|
||||||
|
EXPLAIN QUERY PLAN SELECT * FROM fuel_slips WHERE status = 'pending';
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Frontend Optimization
|
||||||
|
```javascript
|
||||||
|
// vite.config.js
|
||||||
|
export default {
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks: {
|
||||||
|
vendor: ['svelte'],
|
||||||
|
api: ['./src/api.js']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Not**: Prodüksiyon dağıtımından önce mutlaka test ortamında tüm senaryoları doğrulayın.
|
||||||
731
docs/FRONTEND.md
Normal file
731
docs/FRONTEND.md
Normal file
@@ -0,0 +1,731 @@
|
|||||||
|
# Frontend Mimarisi Dokümantasyonu
|
||||||
|
|
||||||
|
Yakıt Takip Sistemi frontend mimarisi, Svelte bileşenleri, state management ve kullanıcı etkileşimi hakkında detaylı bilgi.
|
||||||
|
|
||||||
|
## 📋 İçerlik
|
||||||
|
|
||||||
|
- [Mimari Genel Bakış](#mimari-genel-bakış)
|
||||||
|
- [Component Hiyerarşisi](#component-hiyerarşisi)
|
||||||
|
- [State Management](#state-management)
|
||||||
|
- [Routing](#routing)
|
||||||
|
- [API Entegrasyonu](#api-entegrasyonu)
|
||||||
|
- [Styling ve Tasarım](#styling-ve-tasarım)
|
||||||
|
- [Performance Optimizasyonu](#performance-optimizasyonu)
|
||||||
|
|
||||||
|
## 🏗️ Mimari Genel Bakış
|
||||||
|
|
||||||
|
### Teknoloji Stack
|
||||||
|
- **Framework**: Svelte 4.x
|
||||||
|
- **Build Tool**: Vite 5.x
|
||||||
|
- **Bundler**: Rollup (via Vite)
|
||||||
|
- **CSS**: Pure CSS3 (no framework)
|
||||||
|
- **Icons**: Font Awesome 6.x
|
||||||
|
- **Real-time**: Socket.IO Client
|
||||||
|
- **HTTP Client**: Fetch API (custom wrapper)
|
||||||
|
|
||||||
|
### Tasarım Prensipleri
|
||||||
|
- **Component-based**: Tek sorumluluk ilkesi
|
||||||
|
- **Reactive**: Svelte reaktif değişkenleri
|
||||||
|
- **Event-driven**: Custom events ile haberleşme
|
||||||
|
- **Mobile-first**: Responsive tasarım
|
||||||
|
- **Accessibility**: WCAG 2.1 AA uyumluluğu
|
||||||
|
|
||||||
|
### Proje Yapısı
|
||||||
|
```
|
||||||
|
client/src/
|
||||||
|
├── components/ # Svelte bileşenleri
|
||||||
|
│ ├── LoginView.svelte # Giriş ekranı
|
||||||
|
│ ├── AdminPanel.svelte # Admin yönetim paneli
|
||||||
|
│ ├── FuelManagerPanel.svelte # Yakıt sorumlusu paneli
|
||||||
|
│ ├── InventoryManagerPanel.svelte # Mal sorumlusu paneli
|
||||||
|
│ └── RoleWelcome.svelte # Rol karşılama ekranı
|
||||||
|
├── lib/ # Yardımcı kütüphaneler
|
||||||
|
│ └── numberToWordsTr.js # Sayı→metin çeviri
|
||||||
|
├── api.js # API istemcisi
|
||||||
|
├── app.css # Global stiller
|
||||||
|
├── main.js # Uygulama başlangıcı
|
||||||
|
└── App.svelte # Ana bileşen
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧩 Component Hiyerarşisi
|
||||||
|
|
||||||
|
### App.svelte (Root Component)
|
||||||
|
**Amaç**: Uygulamanın ana bileşeni ve routing mantığı
|
||||||
|
|
||||||
|
#### Sorumluluklar
|
||||||
|
- Oturum yönetimi (localStorage + state)
|
||||||
|
- Component routing (role-based)
|
||||||
|
- Global durum yönetimi
|
||||||
|
- Layout ve tema yönetimi
|
||||||
|
- Error boundaries
|
||||||
|
|
||||||
|
#### Key Features
|
||||||
|
```javascript
|
||||||
|
// State management
|
||||||
|
let user = null;
|
||||||
|
let token = null;
|
||||||
|
let loading = false;
|
||||||
|
let feedback = '';
|
||||||
|
|
||||||
|
// Session persistence
|
||||||
|
onMount(async () => {
|
||||||
|
const storedToken = localStorage.getItem('sessionToken');
|
||||||
|
if (storedToken) {
|
||||||
|
token = storedToken;
|
||||||
|
// Validate session
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event handling
|
||||||
|
function handleLoginSuccess(event) {
|
||||||
|
user = event.detail.user;
|
||||||
|
token = event.detail.token;
|
||||||
|
localStorage.setItem('sessionToken', token);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Template Structure
|
||||||
|
```html
|
||||||
|
<div class="app-shell">
|
||||||
|
<header class="hero">
|
||||||
|
<!-- Hero content with user info -->
|
||||||
|
</header>
|
||||||
|
<main class="content">
|
||||||
|
{#if user}
|
||||||
|
<!-- Role-based component rendering -->
|
||||||
|
{#if user.role === 'admin'}
|
||||||
|
<AdminPanel {token} />
|
||||||
|
{:else if user.role === 'fuel_manager'}
|
||||||
|
<FuelManagerPanel {user} {token} />
|
||||||
|
{:else if user.role === 'inventory_manager'}
|
||||||
|
<InventoryManagerPanel {user} {token} />
|
||||||
|
{:else}
|
||||||
|
<RoleWelcome {user} />
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<LoginView on:success={handleLoginSuccess} />
|
||||||
|
{/if}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### LoginView.svelte
|
||||||
|
**Amaç**: Kullanıcı kimlik doğrulama arayüzü
|
||||||
|
|
||||||
|
#### Features
|
||||||
|
- Form validasyonu
|
||||||
|
- Hata yönetimi
|
||||||
|
- Loading states
|
||||||
|
- Remember me (localStorage)
|
||||||
|
- Custom event dispatch
|
||||||
|
|
||||||
|
#### State Management
|
||||||
|
```javascript
|
||||||
|
let username = '';
|
||||||
|
let password = '';
|
||||||
|
let loading = false;
|
||||||
|
let error = '';
|
||||||
|
|
||||||
|
// Form validasyonu
|
||||||
|
function validateForm() {
|
||||||
|
if (!username.trim() || !password.trim()) {
|
||||||
|
error = 'Kullanıcı adı ve şifre zorunludur.';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// API çağrısı
|
||||||
|
async function handleLogin() {
|
||||||
|
if (!validateForm()) return;
|
||||||
|
|
||||||
|
loading = true;
|
||||||
|
error = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await login(username, password);
|
||||||
|
dispatch('success', {
|
||||||
|
user: response.user,
|
||||||
|
token: response.token
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
error = err.message || 'Giriş başarısız.';
|
||||||
|
} finally {
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### AdminPanel.svelte
|
||||||
|
**Amaç**: Admin yönetim paneli
|
||||||
|
|
||||||
|
#### Modules
|
||||||
|
- Kullanıcı yönetimi (Mal sorumluları)
|
||||||
|
- Araç yönetimi
|
||||||
|
- Birlik yönetimi
|
||||||
|
- Personel yönetimi
|
||||||
|
|
||||||
|
#### Component Pattern
|
||||||
|
```javascript
|
||||||
|
// Tab module state
|
||||||
|
let activeTab = 'managers';
|
||||||
|
let managers = [];
|
||||||
|
let vehicles = [];
|
||||||
|
let units = [];
|
||||||
|
let personnel = [];
|
||||||
|
|
||||||
|
let showCreateModal = false;
|
||||||
|
let editingItem = null;
|
||||||
|
let loading = false;
|
||||||
|
|
||||||
|
// Data fetching
|
||||||
|
async function loadManagers() {
|
||||||
|
loading = true;
|
||||||
|
try {
|
||||||
|
const response = await listInventoryManagers(token);
|
||||||
|
managers = response.managers;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Managers load error:', err);
|
||||||
|
} finally {
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRUD operations
|
||||||
|
async function handleCreateManager(data) {
|
||||||
|
try {
|
||||||
|
await createInventoryManager(data, token);
|
||||||
|
await loadManagers();
|
||||||
|
showCreateModal = false;
|
||||||
|
} catch (err) {
|
||||||
|
error = err.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### FuelManagerPanel.svelte
|
||||||
|
**Amaç**: Yakıt sorumlusu işlemleri paneli
|
||||||
|
|
||||||
|
#### Key Features
|
||||||
|
- Kaynak yönetimi (araç, birlik, personel)
|
||||||
|
- Yakıt fişi oluşturma
|
||||||
|
- Fiş takibi ve yönetimi
|
||||||
|
- PDF indirme
|
||||||
|
- Real-time bildirimler
|
||||||
|
|
||||||
|
#### Socket.IO Integration
|
||||||
|
```javascript
|
||||||
|
import { io } from 'socket.io-client';
|
||||||
|
|
||||||
|
let socket = null;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
socket = io('http://localhost:5005', {
|
||||||
|
auth: { token }
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('fuelSlip:status', (slip) => {
|
||||||
|
// Update UI with new status
|
||||||
|
const index = slips.findIndex(s => s.id === slip.id);
|
||||||
|
if (index !== -1) {
|
||||||
|
slips[index] = slip;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (socket) socket.disconnect();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### InventoryManagerPanel.svelte
|
||||||
|
**Amaç**: Mal sorumlusu onay paneli
|
||||||
|
|
||||||
|
#### Features
|
||||||
|
- Atanan fiş listesi
|
||||||
|
- Onay/reddetme işlemleri
|
||||||
|
- Real-time bildirimler
|
||||||
|
- Filtreleme ve arama
|
||||||
|
|
||||||
|
#### Status Management
|
||||||
|
```javascript
|
||||||
|
let assignedSlips = [];
|
||||||
|
let filter = 'all'; // all, pending, approved, rejected
|
||||||
|
|
||||||
|
function getFilteredSlips() {
|
||||||
|
if (filter === 'all') return assignedSlips;
|
||||||
|
return assignedSlips.filter(slip => slip.status === filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleStatusUpdate(slipId, status, reason = null) {
|
||||||
|
try {
|
||||||
|
const response = await updateFuelSlipStatus(slipId, status, reason, token);
|
||||||
|
|
||||||
|
// Update local state
|
||||||
|
const index = assignedSlips.findIndex(s => s.id === slipId);
|
||||||
|
if (index !== -1) {
|
||||||
|
assignedSlips[index] = response.slip;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
error = err.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 State Management
|
||||||
|
|
||||||
|
### Global State (App.svelte)
|
||||||
|
```javascript
|
||||||
|
// User session state
|
||||||
|
let user = null;
|
||||||
|
let token = null;
|
||||||
|
let loading = false;
|
||||||
|
|
||||||
|
// Session persistence
|
||||||
|
function saveSession(userData, sessionToken) {
|
||||||
|
user = userData;
|
||||||
|
token = sessionToken;
|
||||||
|
localStorage.setItem('sessionToken', sessionToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSession() {
|
||||||
|
user = null;
|
||||||
|
token = null;
|
||||||
|
localStorage.removeItem('sessionToken');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component State Patterns
|
||||||
|
|
||||||
|
#### Form State
|
||||||
|
```javascript
|
||||||
|
// Generic form state pattern
|
||||||
|
let formData = {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
remember: false
|
||||||
|
};
|
||||||
|
|
||||||
|
let errors = {};
|
||||||
|
let touched = {};
|
||||||
|
let isSubmitting = false;
|
||||||
|
|
||||||
|
function validateField(field) {
|
||||||
|
touched[field] = true;
|
||||||
|
// Validation logic
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidForm() {
|
||||||
|
return Object.keys(errors).every(key => !errors[key]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### List State
|
||||||
|
```javascript
|
||||||
|
// Generic list state pattern
|
||||||
|
let items = [];
|
||||||
|
let loading = false;
|
||||||
|
let error = null;
|
||||||
|
let selectedItems = [];
|
||||||
|
|
||||||
|
async function loadItems() {
|
||||||
|
loading = true;
|
||||||
|
error = null;
|
||||||
|
try {
|
||||||
|
const response = await fetchItems(token);
|
||||||
|
items = response.data;
|
||||||
|
} catch (err) {
|
||||||
|
error = err.message;
|
||||||
|
} finally {
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleItemSelect(itemId) {
|
||||||
|
const index = selectedItems.indexOf(itemId);
|
||||||
|
if (index > -1) {
|
||||||
|
selectedItems.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
selectedItems.push(itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reactive State with Svelte
|
||||||
|
```javascript
|
||||||
|
// Reactive statements
|
||||||
|
$: filteredItems = items.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
$: totalAmount = items.reduce((sum, item) => sum + item.amount, 0);
|
||||||
|
|
||||||
|
$: isValid = formData.username && formData.password && !Object.values(errors).some(Boolean);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛣️ Routing
|
||||||
|
|
||||||
|
### Role-based Routing
|
||||||
|
```javascript
|
||||||
|
// App.svelte routing logic
|
||||||
|
{#if user.role === 'admin'}
|
||||||
|
<AdminPanel {token} />
|
||||||
|
{:else if user.role === 'fuel_manager'}
|
||||||
|
<FuelManagerPanel {user} {token} />
|
||||||
|
{:else if user.role === 'inventory_manager'}
|
||||||
|
<InventoryManagerPanel {user} {token} />
|
||||||
|
{:else}
|
||||||
|
<RoleWelcome {user} />
|
||||||
|
{/if}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tab-based Navigation
|
||||||
|
```javascript
|
||||||
|
// Tab management pattern
|
||||||
|
let activeTab = 'overview';
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
{ id: 'overview', label: 'Genel Bakış', icon: 'dashboard' },
|
||||||
|
{ id: 'managers', label: 'Mal Sorumluları', icon: 'users' },
|
||||||
|
{ id: 'vehicles', label: 'Araçlar', icon: 'car' },
|
||||||
|
{ id: 'units', label: 'Birlikler', icon: 'building' },
|
||||||
|
{ id: 'personnel', label: 'Personel', icon: 'user-tie' }
|
||||||
|
];
|
||||||
|
|
||||||
|
function switchTab(tabId) {
|
||||||
|
activeTab = tabId;
|
||||||
|
loadTabData(tabId);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🌐 API Entegrasyonu
|
||||||
|
|
||||||
|
### API Client (api.js)
|
||||||
|
```javascript
|
||||||
|
// Base configuration
|
||||||
|
const BASE_URL = 'http://localhost:5005/api';
|
||||||
|
|
||||||
|
class ApiClient {
|
||||||
|
constructor() {
|
||||||
|
this.token = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setToken(token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
async request(endpoint, options = {}) {
|
||||||
|
const url = `${BASE_URL}${endpoint}`;
|
||||||
|
const config = {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...options.headers
|
||||||
|
},
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.token) {
|
||||||
|
config.headers['X-Session-Token'] = this.token;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(url, config);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const error = await response.json();
|
||||||
|
throw new Error(error.message || 'API request failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authentication methods
|
||||||
|
async login(username, password) {
|
||||||
|
return this.request('/auth/login', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ username, password })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async logout() {
|
||||||
|
return this.request('/auth/logout', { method: 'POST' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRUD methods
|
||||||
|
async get(endpoint) {
|
||||||
|
return this.request(endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
async post(endpoint, data) {
|
||||||
|
return this.request(endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async put(endpoint, data) {
|
||||||
|
return this.request(endpoint, {
|
||||||
|
method: 'PUT',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(endpoint) {
|
||||||
|
return this.request(endpoint, { method: 'DELETE' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singleton instance
|
||||||
|
const api = new ApiClient();
|
||||||
|
export default api;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage in Components
|
||||||
|
```javascript
|
||||||
|
import api from './api.js';
|
||||||
|
|
||||||
|
// Component usage
|
||||||
|
let token = '';
|
||||||
|
|
||||||
|
async function loadData() {
|
||||||
|
try {
|
||||||
|
const data = await api.get('/vehicles');
|
||||||
|
vehicles = data.vehicles;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Load error:', error);
|
||||||
|
errorMessage = error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
isSubmitting = true;
|
||||||
|
const result = await api.post('/vehicles', formData);
|
||||||
|
await loadData();
|
||||||
|
showSuccess('Araç başarıyla eklendi');
|
||||||
|
} catch (error) {
|
||||||
|
showError(error.message);
|
||||||
|
} finally {
|
||||||
|
isSubmitting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 Styling ve Tasarım
|
||||||
|
|
||||||
|
### CSS Architecture
|
||||||
|
```css
|
||||||
|
/* Global variables (app.css) */
|
||||||
|
:root {
|
||||||
|
/* Colors */
|
||||||
|
--primary-color: #4c6ef5;
|
||||||
|
--secondary-color: #6c757d;
|
||||||
|
--success-color: #51cf66;
|
||||||
|
--warning-color: #ffd43b;
|
||||||
|
--danger-color: #ff6b6b;
|
||||||
|
|
||||||
|
/* Spacing */
|
||||||
|
--spacing-xs: 0.25rem;
|
||||||
|
--spacing-sm: 0.5rem;
|
||||||
|
--spacing-md: 1rem;
|
||||||
|
--spacing-lg: 1.5rem;
|
||||||
|
--spacing-xl: 2rem;
|
||||||
|
|
||||||
|
/* Typography */
|
||||||
|
--font-size-xs: 0.75rem;
|
||||||
|
--font-size-sm: 0.875rem;
|
||||||
|
--font-size-base: 1rem;
|
||||||
|
--font-size-lg: 1.125rem;
|
||||||
|
--font-size-xl: 1.25rem;
|
||||||
|
|
||||||
|
/* Shadows */
|
||||||
|
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
|
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
|
||||||
|
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component Styling Pattern
|
||||||
|
```css
|
||||||
|
/* Component-specific styles */
|
||||||
|
.panel-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--spacing-lg);
|
||||||
|
padding: var(--spacing-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-navigation {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
margin-bottom: var(--spacing-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button {
|
||||||
|
padding: var(--spacing-sm) var(--spacing-lg);
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
color: var(--text-muted);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
background: var(--primary-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button.active {
|
||||||
|
color: var(--primary-color);
|
||||||
|
border-bottom-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Responsive Design
|
||||||
|
```css
|
||||||
|
/* Mobile-first responsive design */
|
||||||
|
.content {
|
||||||
|
padding: var(--spacing-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.content {
|
||||||
|
padding: var(--spacing-lg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.content {
|
||||||
|
padding: var(--spacing-xl);
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--spacing-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚡ Performance Optimizasyonu
|
||||||
|
|
||||||
|
### Code Splitting
|
||||||
|
```javascript
|
||||||
|
// Dynamic imports for lazy loading
|
||||||
|
const AdminPanel = lazy(() => import('./components/AdminPanel.svelte'));
|
||||||
|
const FuelManagerPanel = lazy(() => import('./components/FuelManagerPanel.svelte'));
|
||||||
|
|
||||||
|
// Usage with suspense
|
||||||
|
{#if user.role === 'admin'}
|
||||||
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
|
<AdminPanel {token} />
|
||||||
|
</Suspense>
|
||||||
|
{/if}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component Optimization
|
||||||
|
```javascript
|
||||||
|
// Reactivity optimization
|
||||||
|
$: expensiveValue = computeExpensiveValue(data);
|
||||||
|
|
||||||
|
// Memoization with Svelte
|
||||||
|
function memoize(fn) {
|
||||||
|
let lastArgs;
|
||||||
|
let lastResult;
|
||||||
|
|
||||||
|
return (...args) => {
|
||||||
|
if (args.length !== lastArgs?.length || args.some((arg, i) => arg !== lastArgs[i])) {
|
||||||
|
lastArgs = args;
|
||||||
|
lastResult = fn(...args);
|
||||||
|
}
|
||||||
|
return lastResult;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const memoizedFilter = memoize((items, filter) =>
|
||||||
|
items.filter(item => matchesFilter(item, filter))
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Asset Optimization
|
||||||
|
```javascript
|
||||||
|
// vite.config.js
|
||||||
|
export default {
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks: {
|
||||||
|
vendor: ['svelte'],
|
||||||
|
socketio: ['socket.io-client'],
|
||||||
|
utils: ['./src/lib/numberToWordsTr.js']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
assetsInlineLimit: 4096
|
||||||
|
},
|
||||||
|
optimizeDeps: {
|
||||||
|
include: ['svelte', 'socket.io-client']
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bundle Analysis
|
||||||
|
```bash
|
||||||
|
# Bundle analyzer
|
||||||
|
npm install --save-dev rollup-plugin-visualizer
|
||||||
|
|
||||||
|
# Build with analysis
|
||||||
|
npm run build -- --analyze
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Development Tools
|
||||||
|
|
||||||
|
### Svelte DevTools
|
||||||
|
```javascript
|
||||||
|
// DevTools integration
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
import('svelte-devtools');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hot Module Replacement
|
||||||
|
```javascript
|
||||||
|
// Vite HMR configuration
|
||||||
|
export default {
|
||||||
|
server: {
|
||||||
|
hmr: {
|
||||||
|
overlay: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### TypeScript Support (Optional)
|
||||||
|
```javascript
|
||||||
|
// svelte.config.js
|
||||||
|
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
preprocess: vitePreprocess(),
|
||||||
|
compilerOptions: {
|
||||||
|
dev: import.meta.env.DEV
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Not**: Frontend mimarisi sürekli olarak geliştirilmektedir. Yeni özellikler eklerken bu dokümantasyonu güncel tutun.
|
||||||
605
docs/KNOWLEDGE_BASE.md
Normal file
605
docs/KNOWLEDGE_BASE.md
Normal file
@@ -0,0 +1,605 @@
|
|||||||
|
# YTP Bilgi Bankası
|
||||||
|
|
||||||
|
Yakıt Takip Sistemi kapsamlı bilgi bankası - hızlı referans, kılavuzlar ve sorun giderme rehberi.
|
||||||
|
|
||||||
|
## 📋 İçerik
|
||||||
|
|
||||||
|
- [Hızlı Başlangıç](#hızlı-başlangıç)
|
||||||
|
- [Sistem Mimarisi](#sistem-mimarisi)
|
||||||
|
- [Kullanıcı Rolleri ve Yetkileri](#kullanıcı-rolleri-ve-yetkileri)
|
||||||
|
- [İş Akışları](#iş-akışları)
|
||||||
|
- [Yaygın Sorunlar ve Çözümleri](#yaygın-sorunlar-ve-çözümleri)
|
||||||
|
- [Best Practices](#best-practices)
|
||||||
|
- [Kaynaklar ve Referanslar](#kaynaklar-ve-referanslar)
|
||||||
|
|
||||||
|
## 🚀 Hızlı Başlangıç
|
||||||
|
|
||||||
|
### Sistemi 5 Dakikada Çalıştırma
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Projeyi klonlayın
|
||||||
|
git clone <repository-url>
|
||||||
|
cd ytp
|
||||||
|
|
||||||
|
# 2. Bağımlılıkları yükleyin
|
||||||
|
npm install && cd client && npm install && cd ..
|
||||||
|
|
||||||
|
# 3. Veritabanını başlatın
|
||||||
|
npm run prepare:db
|
||||||
|
|
||||||
|
# 4. Sistemi çalıştırın
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# 5. Tarayıcıda açın
|
||||||
|
# Frontend: http://localhost:5173
|
||||||
|
# Backend API: http://localhost:5005/api
|
||||||
|
```
|
||||||
|
|
||||||
|
### Varsayılan Giriş Bilgileri
|
||||||
|
|
||||||
|
| Rol | Kullanıcı Adı | Şifre | Panel |
|
||||||
|
|-----|--------------|-------|-------|
|
||||||
|
| Admin | `admin` | `Admin!123` | [Admin Paneli](#admin-paneli) |
|
||||||
|
| Yakıt Sorumlusu | `yakitsorum` | `Yakit@123` | [Yakıt Sorumlusu Paneli](#yakıt-sorumlusu-paneli) |
|
||||||
|
| Mal Sorumlusu | `malsorum1` | `Mal@123` | [Mal Sorumlusu Paneli](#mal-sorumlusu-paneli) |
|
||||||
|
|
||||||
|
### İlk Yakıt Fişi Oluşturma
|
||||||
|
|
||||||
|
1. **Giriş Yap**: Yakıt sorumlusu ile giriş yapın
|
||||||
|
2. **Kaynak Kontrolü**: Araç, birlik ve personel kayıtlarını kontrol edin
|
||||||
|
3. **Fiş Oluştur**: "Yeni Fiş" butonuna tıklayın
|
||||||
|
4. **Form Doldur**: Tüm zorunlu alanları doldurun
|
||||||
|
5. **Onay Gönder**: Mal sorumlusuna gönder
|
||||||
|
6. **Bildirim Takibi**: Real-time bildirimleri izleyin
|
||||||
|
|
||||||
|
## 🏗️ Sistem Mimarisi
|
||||||
|
|
||||||
|
### Mimari Diyagram
|
||||||
|
```
|
||||||
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||||
|
│ Frontend │ │ Backend │ │ Database │
|
||||||
|
│ (Svelte) │◄──►│ (Express) │◄──►│ (SQLite) │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ - UI Components │ │ - REST API │ │ - users │
|
||||||
|
│ - State Mgmt │ │ - Socket.IO │ │ - vehicles │
|
||||||
|
│ - Routing │ │ - Auth/Authz │ │ - units │
|
||||||
|
│ - API Client │ │ - PDF Generation│ │ - fuel_personnel│
|
||||||
|
└─────────────────┘ └─────────────────┘ │ - fuel_slips │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Teknoloji Stack Karşılaştırması
|
||||||
|
|
||||||
|
| Katman | Teknoloji | Neden? | Alternatifler |
|
||||||
|
|--------|-----------|--------|---------------|
|
||||||
|
| Frontend | Svelte + Vite | Hızlı, küçük bundle, reaktif | React, Vue, Angular |
|
||||||
|
| Backend | Node.js + Express | Hızlı development, JavaScript ekosistemi | Python, PHP, Java |
|
||||||
|
| Database | SQLite3 | Hafif, kurulum gerektirmeyen, taşınabilir | PostgreSQL, MySQL |
|
||||||
|
| Real-time | Socket.IO | WebSocket wrapper, fallback mekanizmaları | Raw WebSocket, SSE |
|
||||||
|
| PDF | PDFKit | Node.js uyumlu, esnek | Puppeteer, jsPDF |
|
||||||
|
|
||||||
|
## 👥 Kullanıcı Rolleri ve Yetkileri
|
||||||
|
|
||||||
|
### Admin (Sistem Yöneticisi)
|
||||||
|
**Yetkiler:**
|
||||||
|
- ✅ Tüm kullanıcıları yönetme
|
||||||
|
- ✅ Mal sorumluları ekleme/güncelleme/silme
|
||||||
|
- ✅ Araç kayıtlarını yönetme
|
||||||
|
- ✅ Birlik bilgilerini yönetme
|
||||||
|
- ✅ Personel kayıtlarını yönetme
|
||||||
|
- ✅ Sistem ayarlarını yapılandırma
|
||||||
|
- ❌ Yakıt fişi oluşturma
|
||||||
|
- ❌ Fiş onaylama/reddetme
|
||||||
|
|
||||||
|
**Kullanım Alanları:**
|
||||||
|
- Sistem kurulum ve bakım
|
||||||
|
- Kullanıcı yönetimi
|
||||||
|
- Temel veri girişi
|
||||||
|
- Raporlama ve analiz
|
||||||
|
|
||||||
|
### Yakıt Sorumlusu
|
||||||
|
**Yetkiler:**
|
||||||
|
- ✅ Yakıt fişi oluşturma
|
||||||
|
- ✅ Fiş durumlarını takip etme
|
||||||
|
- ✅ PDF fiş indirme
|
||||||
|
- ✅ Kaynak bilgilerini görme
|
||||||
|
- ❌ Kullanıcı yönetimi
|
||||||
|
- ❌ Fiş onaylama
|
||||||
|
- ❌ Temel veri düzenleme
|
||||||
|
|
||||||
|
**Kullanım Alanları:**
|
||||||
|
- Günlük yakıt ikmal işlemleri
|
||||||
|
- Fiş oluşturma ve takip
|
||||||
|
- Raporlama
|
||||||
|
|
||||||
|
### Mal Sorumlusu
|
||||||
|
**Yetkiler:**
|
||||||
|
- ✅ Atanan fişleri görme
|
||||||
|
- ✅ Fiş onaylama/reddetme
|
||||||
|
- ✅ Onay/reddetme gerekçesi ekleme
|
||||||
|
- ✅ Atanan fişleri arşivleme
|
||||||
|
- ❌ Fiş oluşturma
|
||||||
|
- ❌ Kullanıcı yönetimi
|
||||||
|
- ❌ Temel veri düzenleme
|
||||||
|
|
||||||
|
**Kullanım Alanları:**
|
||||||
|
- Yakıt ikmal onay süreçleri
|
||||||
|
- Stok takibi
|
||||||
|
- Raporlama
|
||||||
|
|
||||||
|
## 🔄 İş Akışları
|
||||||
|
|
||||||
|
### 1. Kullanıcı Yönetimi Akışı (Admin)
|
||||||
|
```
|
||||||
|
Başlangıç
|
||||||
|
↓
|
||||||
|
Admin Girişi
|
||||||
|
↓
|
||||||
|
"Kullanıcı Yönetimi" → "Mal Sorumluları"
|
||||||
|
↓
|
||||||
|
"Ekle" butonu → Form doldur → Kaydet
|
||||||
|
↓
|
||||||
|
Kullanıcı oluşturuldu → Bilgilendirme
|
||||||
|
↓
|
||||||
|
Bitiş
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Yakıt Fişi Oluşturma Akışı
|
||||||
|
```
|
||||||
|
Başlangıç
|
||||||
|
↓
|
||||||
|
Yakıt Sorumlusu Girişi
|
||||||
|
↓
|
||||||
|
"Yeni Fiş" butonu
|
||||||
|
↓
|
||||||
|
Form doldurma:
|
||||||
|
├─ Tarih seçimi
|
||||||
|
├─ Kuvvet seçimi
|
||||||
|
├─ Birlik seçimi
|
||||||
|
├─ Araç seçimi
|
||||||
|
├─ Yakıt bilgileri
|
||||||
|
├─ Personel seçimi
|
||||||
|
└─ Mal sorumlusu atama
|
||||||
|
↓
|
||||||
|
"Oluştur" butonu
|
||||||
|
↓
|
||||||
|
Validasyon → Veritabanı kayıt
|
||||||
|
↓
|
||||||
|
Mal sorumlusuna bildirim
|
||||||
|
↓
|
||||||
|
PDF fiş oluştur (opsiyonel)
|
||||||
|
↓
|
||||||
|
Bitiş
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Fiş Onay Akışı
|
||||||
|
```
|
||||||
|
Başlangıç
|
||||||
|
↓
|
||||||
|
Mal Sorumlusu Girişi
|
||||||
|
↓
|
||||||
|
"Atanan Fişler" listesi
|
||||||
|
↓
|
||||||
|
Fiş seçimi → Detay görüntüle
|
||||||
|
↓
|
||||||
|
Karar verme:
|
||||||
|
├─ "Onayla" → Durum: approved
|
||||||
|
└─ "Reddet" → Gerekçe gir → Durum: rejected
|
||||||
|
↓
|
||||||
|
Yakıt sorumlusuna bildirim
|
||||||
|
↓
|
||||||
|
Bitiş
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Real-time Bildirim Akışı
|
||||||
|
```
|
||||||
|
Olay Tetiklenir
|
||||||
|
↓
|
||||||
|
Server Event Oluştur
|
||||||
|
↓
|
||||||
|
Socket.IO Emit
|
||||||
|
↓
|
||||||
|
İlgili Client'a Gönder
|
||||||
|
↓
|
||||||
|
UI Güncellenir
|
||||||
|
↓
|
||||||
|
Kullanıcı Bilgilendirilir
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Yaygın Sorunlar ve Çözümleri
|
||||||
|
|
||||||
|
### Giriş ve Oturum Sorunları
|
||||||
|
|
||||||
|
#### Sorun: "Kullanıcı adı veya şifre hatalı"
|
||||||
|
**Nedenler:**
|
||||||
|
- Yanlış kullanıcı adı/şifre
|
||||||
|
- Büyük/küçük harf duyarlılığı
|
||||||
|
- Boşluk karakterleri
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```bash
|
||||||
|
# Varsayılan kullanıcıları kontrol et
|
||||||
|
sqlite3 data/app.db "SELECT username, role FROM users;"
|
||||||
|
|
||||||
|
# Şifre sıfırlama (admin için)
|
||||||
|
sqlite3 data/app.db "UPDATE users SET password = 'Admin!123' WHERE username = 'admin';"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sorun: "Oturum bulunamadı"
|
||||||
|
**Nedenler:**
|
||||||
|
- Token süresi dolmuş
|
||||||
|
- Browser storage temizlenmiş
|
||||||
|
- Sunucu yeniden başlatılmış
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```javascript
|
||||||
|
// Browser console'dan kontrol et
|
||||||
|
localStorage.getItem('sessionToken');
|
||||||
|
|
||||||
|
// Manuel temizleme
|
||||||
|
localStorage.removeItem('sessionToken');
|
||||||
|
location.reload();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Veritabanı Sorunları
|
||||||
|
|
||||||
|
#### Sorun: "Veritabanı okunamadı"
|
||||||
|
**Nedenler:**
|
||||||
|
- Veritabanı dosyası yok
|
||||||
|
- İzin sorunları
|
||||||
|
- Dosya kilitli
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```bash
|
||||||
|
# Veritabanını yeniden oluştur
|
||||||
|
rm data/app.db
|
||||||
|
npm run prepare:db
|
||||||
|
|
||||||
|
# İzinleri kontrol et
|
||||||
|
ls -la data/app.db
|
||||||
|
chmod 664 data/app.db
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sorun: "Bu kullanici adi zaten mevcut"
|
||||||
|
**Nedenler:**
|
||||||
|
- Unique constraint ihlali
|
||||||
|
- Önceki kayıt silinmemiş
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```sql
|
||||||
|
-- Mevcut kullanıcıları listele
|
||||||
|
SELECT id, username, role FROM users;
|
||||||
|
|
||||||
|
-- Kullanıcıyı sil (ID'ye göre)
|
||||||
|
DELETE FROM users WHERE id = 3;
|
||||||
|
```
|
||||||
|
|
||||||
|
### API ve Bağlantı Sorunları
|
||||||
|
|
||||||
|
#### Sorun: "Network Error"
|
||||||
|
**Nedenler:**
|
||||||
|
- Backend çalışmıyor
|
||||||
|
- Port çakışması
|
||||||
|
- Firewall engeli
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```bash
|
||||||
|
# Port durumunu kontrol et
|
||||||
|
lsof -i :5005
|
||||||
|
|
||||||
|
# Backend'i yeniden başlat
|
||||||
|
npm run start:server
|
||||||
|
|
||||||
|
# Port değiştir
|
||||||
|
PORT=3000 npm run start:server
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sorun: "CORS hatası"
|
||||||
|
**Nedenler:**
|
||||||
|
- Origin mismatch
|
||||||
|
- CORS ayarları eksik
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```javascript
|
||||||
|
// server/index.js CORS ayarları
|
||||||
|
app.use(cors({
|
||||||
|
origin: ['http://localhost:5173', 'http://localhost:3000'],
|
||||||
|
credentials: true
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend Sorunları
|
||||||
|
|
||||||
|
#### Sorun: Component yüklenmiyor
|
||||||
|
**Nedenler:**
|
||||||
|
- JavaScript error
|
||||||
|
- Import hataları
|
||||||
|
- Build sorunları
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```bash
|
||||||
|
# Frontend'i yeniden build et
|
||||||
|
cd client
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Development modunda kontrol et
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sorun: Socket.IO bağlantı kurulamıyor
|
||||||
|
**Nedenler:**
|
||||||
|
- Token geçersiz
|
||||||
|
- Server kapalı
|
||||||
|
- WebSocket engellendi
|
||||||
|
|
||||||
|
**Çözümler:**
|
||||||
|
```javascript
|
||||||
|
// Browser console'da test
|
||||||
|
const socket = io('http://localhost:5005');
|
||||||
|
socket.on('connect', () => console.log('Connected'));
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Best Practices
|
||||||
|
|
||||||
|
### Development Best Practices
|
||||||
|
|
||||||
|
#### 1. Code Organization
|
||||||
|
```javascript
|
||||||
|
// ✅ İyi pratik - Component based structure
|
||||||
|
src/
|
||||||
|
├── components/
|
||||||
|
│ ├── auth/
|
||||||
|
│ ├── admin/
|
||||||
|
│ └── shared/
|
||||||
|
├── lib/
|
||||||
|
├── api/
|
||||||
|
└── styles/
|
||||||
|
|
||||||
|
// ❌ Kötü pratik - Tüm dosyaları tek dizinde
|
||||||
|
src/
|
||||||
|
├── LoginView.svelte
|
||||||
|
├── AdminPanel.svelte
|
||||||
|
├── api.js
|
||||||
|
└── styles.css
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Error Handling
|
||||||
|
```javascript
|
||||||
|
// ✅ İyi pratik - Spesifik error handling
|
||||||
|
async function createFuelSlip(data) {
|
||||||
|
try {
|
||||||
|
const response = await api.post('/fuel-slips', data);
|
||||||
|
return response.slip;
|
||||||
|
} catch (error) {
|
||||||
|
if (error.status === 409) {
|
||||||
|
throw new Error('Bu fiş zaten mevcut');
|
||||||
|
} else if (error.status === 400) {
|
||||||
|
throw new Error('Form verileri geçersiz');
|
||||||
|
}
|
||||||
|
throw new Error('Fiş oluşturulamadı');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Kötü pratik - Generic error handling
|
||||||
|
async function createFuelSlip(data) {
|
||||||
|
try {
|
||||||
|
return await api.post('/fuel-slips', data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error); // Silent fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. State Management
|
||||||
|
```javascript
|
||||||
|
// ✅ İyi pratik - Minimal reactivity
|
||||||
|
let search = '';
|
||||||
|
let items = [];
|
||||||
|
|
||||||
|
$: filteredItems = items.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(search.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
// ❌ Kötü pratik - Unnecessary reactivity
|
||||||
|
$: searchLower = search.toLowerCase();
|
||||||
|
$: filteredItems = items.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(searchLower)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Security Best Practices
|
||||||
|
|
||||||
|
#### 1. Input Validation
|
||||||
|
```javascript
|
||||||
|
// ✅ İyi pratik - Server-side validation
|
||||||
|
app.post('/api/vehicles', (req, res) => {
|
||||||
|
const { brand, model, year, plate } = req.body;
|
||||||
|
|
||||||
|
// Server-side validation
|
||||||
|
if (!brand || !model || !year || !plate) {
|
||||||
|
return res.status(400).json({ message: 'All fields required' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (year < 1990 || year > new Date().getFullYear() + 1) {
|
||||||
|
return res.status(400).json({ message: 'Invalid year' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process valid data
|
||||||
|
});
|
||||||
|
|
||||||
|
// ❌ Kötü pratik - Sadece client-side validation
|
||||||
|
// Frontend validation bypass edilebilir
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Session Management
|
||||||
|
```javascript
|
||||||
|
// ✅ İyi pratik - Secure session handling
|
||||||
|
function createSession(user) {
|
||||||
|
const token = crypto.randomBytes(32).toString('hex');
|
||||||
|
const session = {
|
||||||
|
id: user.id,
|
||||||
|
role: user.role,
|
||||||
|
createdAt: Date.now(),
|
||||||
|
expiresAt: Date.now() + (24 * 60 * 60 * 1000) // 24 hours
|
||||||
|
};
|
||||||
|
|
||||||
|
sessions.set(token, session);
|
||||||
|
return { token, session };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Kötü pratik - Predictable tokens
|
||||||
|
function createSession(user) {
|
||||||
|
const token = `${user.id}-${Date.now()}`; // Predictable!
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Best Practices
|
||||||
|
|
||||||
|
#### 1. Database Queries
|
||||||
|
```javascript
|
||||||
|
// ✅ İyi pratik - Efficient queries
|
||||||
|
async function getFuelSlipsByStatus(status) {
|
||||||
|
return db.all(`
|
||||||
|
SELECT fs.*, u.display_name as inventoryManagerName
|
||||||
|
FROM fuel_slips fs
|
||||||
|
LEFT JOIN users u ON u.id = fs.inventory_manager_id
|
||||||
|
WHERE fs.status = ?
|
||||||
|
ORDER BY fs.created_at DESC
|
||||||
|
`, [status]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Kötü pratik - N+1 query problem
|
||||||
|
async function getFuelSlipsByStatus(status) {
|
||||||
|
const slips = await db.all(`
|
||||||
|
SELECT * FROM fuel_slips WHERE status = ?
|
||||||
|
`, [status]);
|
||||||
|
|
||||||
|
// N+1 queries!
|
||||||
|
for (const slip of slips) {
|
||||||
|
const user = await db.get(`
|
||||||
|
SELECT display_name FROM users WHERE id = ?
|
||||||
|
`, [slip.inventory_manager_id]);
|
||||||
|
slip.inventoryManagerName = user.display_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return slips;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Component Optimization
|
||||||
|
```javascript
|
||||||
|
// ✅ İyi pratik - Lazy loading
|
||||||
|
const AdminPanel = lazy(() => import('./components/AdminPanel.svelte'));
|
||||||
|
|
||||||
|
// Usage
|
||||||
|
{#if user.role === 'admin'}
|
||||||
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
|
<AdminPanel {token} />
|
||||||
|
</Suspense>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
// ❌ Kötü pratik - Her zaman tüm component'leri yüklemek
|
||||||
|
import AdminPanel from './components/AdminPanel.svelte';
|
||||||
|
import FuelManagerPanel from './components/FuelManagerPanel.svelte';
|
||||||
|
// ... tüm component'ler import edildi
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔗 Kaynaklar ve Referanslar
|
||||||
|
|
||||||
|
### Dokümantasyon Linkleri
|
||||||
|
- [README.md](../README.md) - Proje genel bakış
|
||||||
|
- [API.md](API.md) - API dokümantasyonu
|
||||||
|
- [DATABASE.md](DATABASE.md) - Veritabanı şeması
|
||||||
|
- [STRUCTURE.md](STRUCTURE.md) - Proje yapısı
|
||||||
|
- [DEPLOYMENT.md](DEPLOYMENT.md) - Dağıtım kılavuzu
|
||||||
|
- [FRONTEND.md](FRONTEND.md) - Frontend mimarisi
|
||||||
|
|
||||||
|
### External Resources
|
||||||
|
|
||||||
|
#### Teknoloji Dokümantasyonları
|
||||||
|
- [Svelte Documentation](https://svelte.dev/docs)
|
||||||
|
- [Express.js Guide](https://expressjs.com/en/guide/)
|
||||||
|
- [Socket.IO Documentation](https://socket.io/docs/)
|
||||||
|
- [SQLite Documentation](https://www.sqlite.org/docs.html)
|
||||||
|
- [Vite Documentation](https://vitejs.dev/guide/)
|
||||||
|
|
||||||
|
#### Development Tools
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Svelte Extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode)
|
||||||
|
- [SQLite Browser](https://sqlitebrowser.org/) - Veritabanı yönetimi
|
||||||
|
- [Postman](https://www.postman.com/) - API testing
|
||||||
|
- [Git](https://git-scm.com/) - Versiyon kontrolü
|
||||||
|
|
||||||
|
#### Learning Resources
|
||||||
|
- [MDN Web Docs](https://developer.mozilla.org/) - Web teknolojileri
|
||||||
|
- [JavaScript Info](https://javascript.info/) - JavaScript öğrenme
|
||||||
|
- [CSS Tricks](https://css-tricks.com/) - CSS teknikleri
|
||||||
|
- [Node.js Best Practices](https://github.com/goldbergyoni/nodebestpractices) - Node.js pratikleri
|
||||||
|
|
||||||
|
### Komut Referansı
|
||||||
|
|
||||||
|
#### Geliştirme Komutları
|
||||||
|
```bash
|
||||||
|
npm run dev # Geliştirme sunucusu
|
||||||
|
npm run start:server # Sadece backend
|
||||||
|
cd client && npm run dev # Sadece frontend
|
||||||
|
npm run prepare:db # Veritabanı başlangıç
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Production Komutları
|
||||||
|
```bash
|
||||||
|
npm run build # Frontend build
|
||||||
|
npm start # Production sunucusu
|
||||||
|
pm2 start ecosystem.config.js # PM2 ile başlat
|
||||||
|
docker-compose up -d # Docker ile başlat
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Veritabanı Komutları
|
||||||
|
```bash
|
||||||
|
sqlite3 data/app.db # Veritabanına bağlan
|
||||||
|
sqlite3 data/app.db ".tables" # Tabloları listele
|
||||||
|
sqlite3 data/app.db ".schema" # Şemayı göster
|
||||||
|
sqlite3 data/app.db ".backup backup.db" # Yedek al
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hızlı Referans Kartları
|
||||||
|
|
||||||
|
#### API Endpoint'leri
|
||||||
|
```
|
||||||
|
Authentication:
|
||||||
|
POST /api/auth/login
|
||||||
|
POST /api/auth/logout
|
||||||
|
GET /api/session
|
||||||
|
|
||||||
|
Admin Operations:
|
||||||
|
GET/POST/PUT/DELETE /api/inventory-managers
|
||||||
|
GET/POST/PUT/DELETE /api/vehicles
|
||||||
|
GET/POST/PUT/DELETE /api/units
|
||||||
|
GET/POST/PUT/DELETE /api/fuel-personnel
|
||||||
|
|
||||||
|
Fuel Operations:
|
||||||
|
GET /api/fuel/resources
|
||||||
|
GET /api/fuel-slips
|
||||||
|
POST /api/fuel-slips
|
||||||
|
GET /api/fuel-slips/:id/pdf
|
||||||
|
PATCH /api/fuel-slips/:id/status
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Varsayılan Veriler
|
||||||
|
```
|
||||||
|
Users:
|
||||||
|
- admin/Admin!123 (admin)
|
||||||
|
- yakitsorum/Yakit@123 (fuel_manager)
|
||||||
|
- malsorum1/Mal@123 (inventory_manager)
|
||||||
|
|
||||||
|
Vehicles:
|
||||||
|
- Ford Transit 2021 (34 AYT 312)
|
||||||
|
- Isuzu NPR 2019 (34 FZT 908)
|
||||||
|
|
||||||
|
Forces:
|
||||||
|
- MSB, K.K.K., Dz.K.K., Hv.K.K., SGK, Gnkur. Bşk., Hrt.Gn.K.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Not**: Bu bilgi bankesi sürekli güncellenmektedir. Yeni sorunlar ve çözümler eklenecektir.
|
||||||
429
docs/STRUCTURE.md
Normal file
429
docs/STRUCTURE.md
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
# Proje Yapısı Dokümantasyonu
|
||||||
|
|
||||||
|
Yakıt Takip Sistemi proje dosya yapısı, organizasyon ve mimari desenleri hakkında detaylı bilgi.
|
||||||
|
|
||||||
|
## 📋 İçerik
|
||||||
|
|
||||||
|
- [Genel Bakış](#genel-bakış)
|
||||||
|
- [Dizin Yapısı](#dizin-yapısı)
|
||||||
|
- [Frontend Mimarisi](#frontend-mimarisi)
|
||||||
|
- [Backend Mimarisi](#backend-mimarisi)
|
||||||
|
- [Veri Akışı](#veri-akışı)
|
||||||
|
- [Kurallar ve Standartlar](#kurallar-ve-standartlar)
|
||||||
|
|
||||||
|
## 🎯 Genel Bakış
|
||||||
|
|
||||||
|
### Proje Türü
|
||||||
|
- **Tip**: Full-stack Web Uygulaması
|
||||||
|
- **Mimari**: Client-Server
|
||||||
|
- **Deployment**: Monolitik
|
||||||
|
- **Database**: SQLite (file-based)
|
||||||
|
|
||||||
|
### Teknoloji Stack
|
||||||
|
- **Frontend**: Svelte + Vite
|
||||||
|
- **Backend**: Node.js + Express
|
||||||
|
- **Real-time**: Socket.IO
|
||||||
|
- **Database**: SQLite3
|
||||||
|
- **Styling**: CSS3 (no framework)
|
||||||
|
- **Build**: Vite
|
||||||
|
|
||||||
|
### Geliştirme Yaklaşımı
|
||||||
|
- **Component-based**: Bileşen tabanlı geliştirme
|
||||||
|
- **API-first**: API odaklı tasarım
|
||||||
|
- **Role-based**: Rol bazlı yetkilendirme
|
||||||
|
- **Responsive**: Mobil uyumlu tasarım
|
||||||
|
|
||||||
|
## 📁 Dizin Yapısı
|
||||||
|
|
||||||
|
```
|
||||||
|
ytp/
|
||||||
|
├── 📂 client/ # Frontend uygulaması
|
||||||
|
│ ├── 📂 src/
|
||||||
|
│ │ ├── 📂 components/ # Svelte bileşenleri
|
||||||
|
│ │ │ ├── 📄 LoginView.svelte
|
||||||
|
│ │ │ ├── 📄 AdminPanel.svelte
|
||||||
|
│ │ │ ├── 📄 FuelManagerPanel.svelte
|
||||||
|
│ │ │ ├── 📄 InventoryManagerPanel.svelte
|
||||||
|
│ │ │ └── 📄 RoleWelcome.svelte
|
||||||
|
│ │ ├── 📂 lib/ # Yardımcı kütüphaneler
|
||||||
|
│ │ │ └── 📄 numberToWordsTr.js
|
||||||
|
│ │ ├── 📄 api.js # API istemcisi
|
||||||
|
│ │ ├── 📄 app.css # Ana stil dosyası
|
||||||
|
│ │ ├── 📄 main.js # Uygulama giriş noktası
|
||||||
|
│ │ └── 📄 App.svelte # Ana uygulama bileşeni
|
||||||
|
│ ├── 📄 index.html # HTML template
|
||||||
|
│ ├── 📄 package.json # Frontend bağımlılıkları
|
||||||
|
│ ├── 📄 vite.config.js # Vite yapılandırması
|
||||||
|
│ └── 📄 svelte.config.js # Svelte yapılandırması
|
||||||
|
├── 📂 server/ # Backend uygulaması
|
||||||
|
│ ├── 📄 index.js # Express sunucusu
|
||||||
|
│ ├── 📄 db.js # Veritabanı işlemleri
|
||||||
|
│ └── 📄 db-init.js # Veritabanı başlangıç
|
||||||
|
├── 📂 data/ # Veritabanı dosyaları
|
||||||
|
│ └── 📄 app.db # SQLite veritabanı
|
||||||
|
├── 📂 docs/ # Dokümantasyon
|
||||||
|
│ ├── 📄 README.md
|
||||||
|
│ ├── 📄 API.md
|
||||||
|
│ ├── 📄 DATABASE.md
|
||||||
|
│ ├── 📄 STRUCTURE.md
|
||||||
|
│ └── 📄 DEPLOYMENT.md
|
||||||
|
├── 📄 package.json # Proje bağımlılıkları
|
||||||
|
└── 📄 README.md # Proje açıklaması
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 Frontend Mimarisi
|
||||||
|
|
||||||
|
### Component Hiyerarşisi
|
||||||
|
```
|
||||||
|
App.svelte (Ana uygulama)
|
||||||
|
├── LoginView.svelte (Giriş)
|
||||||
|
├── RoleWelcome.svelte (Karşılama)
|
||||||
|
├── AdminPanel.svelte (Admin paneli)
|
||||||
|
├── FuelManagerPanel.svelte (Yakıt sorumlusu)
|
||||||
|
└── InventoryManagerPanel.svelte (Mal sorumlusu)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dosya Açıklamaları
|
||||||
|
|
||||||
|
#### App.svelte
|
||||||
|
- **Amaç**: Ana uygulama bileşeni ve routing
|
||||||
|
- **Sorumluluklar**:
|
||||||
|
- Oturum yönetimi
|
||||||
|
- Routing mantığı
|
||||||
|
- Global durum yönetimi
|
||||||
|
- Temel layout
|
||||||
|
|
||||||
|
#### components/LoginView.svelte
|
||||||
|
- **Amaç**: Kullanıcı giriş arayüzü
|
||||||
|
- **Features**:
|
||||||
|
- Form validasyonu
|
||||||
|
- Hata yönetimi
|
||||||
|
- Başarılı giriş olayı
|
||||||
|
- Responsive tasarım
|
||||||
|
|
||||||
|
#### components/AdminPanel.svelte
|
||||||
|
- **Amaç**: Admin yönetim paneli
|
||||||
|
- **Features**:
|
||||||
|
- CRUD operasyonları
|
||||||
|
- Tablo gösterimi
|
||||||
|
- Form yönetimi
|
||||||
|
- Modal dialoglar
|
||||||
|
|
||||||
|
#### components/FuelManagerPanel.svelte
|
||||||
|
- **Amaç**: Yakıt sorumlusu paneli
|
||||||
|
- **Features**:
|
||||||
|
- Fiş oluşturma
|
||||||
|
- Kaynak yönetimi
|
||||||
|
- Socket.IO entegrasyonu
|
||||||
|
- PDF indirme
|
||||||
|
|
||||||
|
#### components/InventoryManagerPanel.svelte
|
||||||
|
- **Amaç**: Mal sorumlusu paneli
|
||||||
|
- **Features**:
|
||||||
|
- Fiş onay/reddetme
|
||||||
|
- Atanan fiş listesi
|
||||||
|
- Socket.IO bildirimleri
|
||||||
|
- Durum yönetimi
|
||||||
|
|
||||||
|
#### lib/numberToWordsTr.js
|
||||||
|
- **Amaç**: Sayıları Türkçe metne çevirme
|
||||||
|
- **Kullanım**: PDF fişlerde rakam→yazı dönüşümü
|
||||||
|
|
||||||
|
#### api.js
|
||||||
|
- **Amaç**: API istemcisi
|
||||||
|
- **Features**:
|
||||||
|
- HTTP istekleri
|
||||||
|
- Error handling
|
||||||
|
- Token yönetimi
|
||||||
|
- Base URL konfigürasyonu
|
||||||
|
|
||||||
|
### State Management
|
||||||
|
- **Local State**: Svelte reaktif değişkenleri
|
||||||
|
- **Session Storage**: Token ve oturum bilgileri
|
||||||
|
- **Prop Drilling**: Component veri akışı
|
||||||
|
- **Custom Events**: Component haberleşmesi
|
||||||
|
|
||||||
|
### Styling Architecture
|
||||||
|
- **CSS3**: Modern CSS özellikleri
|
||||||
|
- **CSS Variables**: Tema ve renk yönetimi
|
||||||
|
- **Flexbox/Grid**: Responsive layout
|
||||||
|
- **Mobile-first**: Responsive tasarım yaklaşımı
|
||||||
|
|
||||||
|
## ⚙️ Backend Mimarisi
|
||||||
|
|
||||||
|
### Server Structure
|
||||||
|
```
|
||||||
|
server/
|
||||||
|
├── index.js # Ana Express sunucusu
|
||||||
|
├── db.js # Veritabanı katmanı
|
||||||
|
└── db-init.js # Veritabanı başlangıç
|
||||||
|
```
|
||||||
|
|
||||||
|
### index.js - Express Sunucusu
|
||||||
|
**Amaç**: Ana uygulama sunucusu
|
||||||
|
|
||||||
|
**Bileşenler**:
|
||||||
|
- **HTTP Server**: Express.js uygulaması
|
||||||
|
- **WebSocket Server**: Socket.IO sunucusu
|
||||||
|
- **Authentication**: Token bazlı kimlik doğrulama
|
||||||
|
- **Authorization**: Rol bazlı yetkilendirme
|
||||||
|
- **API Routes**: RESTful endpoint'ler
|
||||||
|
- **Middleware**: CORS, JSON parsing, logging
|
||||||
|
|
||||||
|
**Route Structure**:
|
||||||
|
```javascript
|
||||||
|
// Authentication
|
||||||
|
POST /api/auth/login
|
||||||
|
POST /api/auth/logout
|
||||||
|
GET /api/session
|
||||||
|
|
||||||
|
// Admin routes
|
||||||
|
CRUD /api/inventory-managers
|
||||||
|
CRUD /api/vehicles
|
||||||
|
CRUD /api/units
|
||||||
|
CRUD /api/fuel-personnel
|
||||||
|
|
||||||
|
// Fuel Manager routes
|
||||||
|
GET /api/fuel/resources
|
||||||
|
GET /api/fuel-slips
|
||||||
|
POST /api/fuel-slips
|
||||||
|
GET /api/fuel-slips/:id/pdf
|
||||||
|
|
||||||
|
// Inventory Manager routes
|
||||||
|
GET /api/fuel-slips/assigned
|
||||||
|
PATCH /api/fuel-slips/:id/status
|
||||||
|
```
|
||||||
|
|
||||||
|
### db.js - Veritabanı Katmanı
|
||||||
|
**Amaç**: Veritabanı işlemleri ve model yönetimi
|
||||||
|
|
||||||
|
**Features**:
|
||||||
|
- **Connection Management**: SQLite bağlantısı
|
||||||
|
- **Schema Management**: Tablo oluşturma ve migration
|
||||||
|
- **CRUD Operations**: Create, Read, Update, Delete
|
||||||
|
- **Data Validation**: Veri doğrulama ve constraint'ler
|
||||||
|
- **Error Handling**: Veritabanı hata yönetimi
|
||||||
|
- **Sample Data**: Başlangıç verileri
|
||||||
|
|
||||||
|
**Function Groups**:
|
||||||
|
```javascript
|
||||||
|
// User management
|
||||||
|
getUserByUsername()
|
||||||
|
createInventoryManager()
|
||||||
|
listInventoryManagers()
|
||||||
|
updateInventoryManager()
|
||||||
|
deleteInventoryManager()
|
||||||
|
|
||||||
|
// Vehicle management
|
||||||
|
createVehicle()
|
||||||
|
listVehicles()
|
||||||
|
updateVehicle()
|
||||||
|
deleteVehicle()
|
||||||
|
getVehicleById()
|
||||||
|
|
||||||
|
// Unit management
|
||||||
|
createUnit()
|
||||||
|
listUnits()
|
||||||
|
updateUnit()
|
||||||
|
deleteUnit()
|
||||||
|
getUnitById()
|
||||||
|
|
||||||
|
// Personnel management
|
||||||
|
createFuelPersonnel()
|
||||||
|
listFuelPersonnel()
|
||||||
|
updateFuelPersonnel()
|
||||||
|
deleteFuelPersonnel()
|
||||||
|
getFuelPersonnelById()
|
||||||
|
|
||||||
|
// Fuel slip management
|
||||||
|
createFuelSlip()
|
||||||
|
listFuelSlips()
|
||||||
|
listFuelSlipsByInventoryManager()
|
||||||
|
getFuelSlipById()
|
||||||
|
updateFuelSlipStatus()
|
||||||
|
```
|
||||||
|
|
||||||
|
### db-init.js - Veritabanı Başlangıç
|
||||||
|
**Amaç**: Veritabanı başlangıç ve örnek veriler
|
||||||
|
|
||||||
|
**Features**:
|
||||||
|
- **Schema Creation**: Tablo oluşturma script'i
|
||||||
|
- **Sample Data**: Test verileri
|
||||||
|
- **Migration**: Versiyon geçişleri
|
||||||
|
- **Data Seeding**: Başlangıç verileri
|
||||||
|
|
||||||
|
## 🔄 Veri Akışı
|
||||||
|
|
||||||
|
### Authentication Flow
|
||||||
|
```
|
||||||
|
1. Kullanıcı giriş formu doldurur
|
||||||
|
2. Client → POST /api/auth/login
|
||||||
|
3. Server validates credentials
|
||||||
|
4. Server creates session token
|
||||||
|
5. Server returns token + user data
|
||||||
|
6. Client stores token (localStorage)
|
||||||
|
7. Client includes token in headers
|
||||||
|
8. Server validates token (middleware)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Real-time Communication Flow
|
||||||
|
```
|
||||||
|
1. Client connects with token
|
||||||
|
2. Server validates and authenticates
|
||||||
|
3. Server adds client to appropriate rooms
|
||||||
|
4. Server emits events to relevant clients
|
||||||
|
5. Client handles events and updates UI
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fuel Slip Creation Flow
|
||||||
|
```
|
||||||
|
1. Fuel Manager fills form
|
||||||
|
2. Client validates form data
|
||||||
|
3. Client → POST /api/fuel-slips
|
||||||
|
4. Server validates data
|
||||||
|
5. Server creates fuel slip
|
||||||
|
6. Server generates slip number
|
||||||
|
7. Server saves to database
|
||||||
|
8. Server emits to Inventory Manager
|
||||||
|
9. Server emits confirmation to Fuel Manager
|
||||||
|
10. Client updates UI
|
||||||
|
```
|
||||||
|
|
||||||
|
### Approval Flow
|
||||||
|
```
|
||||||
|
1. Inventory Manager reviews slip
|
||||||
|
2. Client → PATCH /api/fuel-slips/:id/status
|
||||||
|
3. Server validates permissions
|
||||||
|
4. Server updates status
|
||||||
|
5. Server emits to Fuel Manager
|
||||||
|
6. Server emits confirmation to Inventory Manager
|
||||||
|
7. Client updates UI
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📏 Kurallar ve Standartlar
|
||||||
|
|
||||||
|
### Kodlama Standartları
|
||||||
|
|
||||||
|
#### JavaScript/Node.js
|
||||||
|
- **ES6+**: Modern JavaScript özellikleri
|
||||||
|
- **CamelCase**: Değişken ve fonksiyon isimleri
|
||||||
|
- **PascalCase**: Class ve constructor isimleri
|
||||||
|
- **UPPER_SNAKE_CASE**: Constant'lar
|
||||||
|
- **Async/Await**: Asenkron operasyonlar
|
||||||
|
- **Error Handling**: Try-catch blokları
|
||||||
|
|
||||||
|
#### Svelte
|
||||||
|
- **Component-based**: Tek sorumluluk ilkesi
|
||||||
|
- **Props**: Veri akışı parent → child
|
||||||
|
- **Events**: Haberleşme child → parent
|
||||||
|
- **Reactive**: $: reaktif değişkenler
|
||||||
|
- **Lifecycle**: onMount, onDestroy
|
||||||
|
|
||||||
|
#### CSS
|
||||||
|
- **BEM-like**: Component bazlı naming
|
||||||
|
- **Mobile-first**: Responsive yaklaşım
|
||||||
|
- **Flexbox/Grid**: Modern layout
|
||||||
|
- **CSS Variables**: Tema yönetimi
|
||||||
|
- **Minification**: Prodüksiyon için
|
||||||
|
|
||||||
|
### Dosya Organizasyonu
|
||||||
|
|
||||||
|
#### Frontend
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── components/ # Svelte components
|
||||||
|
│ ├── View*.svelte # Page-level components
|
||||||
|
│ ├── *Panel.svelte # Feature components
|
||||||
|
│ └── *.svelte # Reusable components
|
||||||
|
├── lib/ # Utility libraries
|
||||||
|
├── api.js # API client
|
||||||
|
├── main.js # App entry point
|
||||||
|
└── App.svelte # Root component
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Backend
|
||||||
|
```
|
||||||
|
server/
|
||||||
|
├── index.js # Main server
|
||||||
|
├── db.js # Database layer
|
||||||
|
└── db-init.js # Database initialization
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Design Standartları
|
||||||
|
|
||||||
|
#### RESTful Conventions
|
||||||
|
- **GET**: Veri okuma
|
||||||
|
- **POST**: Veri oluşturma
|
||||||
|
- **PUT**: Tam veri güncelleme
|
||||||
|
- **PATCH**: Kısmi veri güncelleme
|
||||||
|
- **DELETE**: Veri silme
|
||||||
|
|
||||||
|
#### Response Format
|
||||||
|
```javascript
|
||||||
|
// Success
|
||||||
|
{
|
||||||
|
"data": { ... },
|
||||||
|
"message": "Operation successful"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error
|
||||||
|
{
|
||||||
|
"error": "Error description",
|
||||||
|
"message": "User-friendly message"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### HTTP Status Codes
|
||||||
|
- **200**: Success
|
||||||
|
- **201**: Created
|
||||||
|
- **204**: No Content
|
||||||
|
- **400**: Bad Request
|
||||||
|
- **401**: Unauthorized
|
||||||
|
- **403**: Forbidden
|
||||||
|
- **404**: Not Found
|
||||||
|
- **409**: Conflict
|
||||||
|
- **500**: Server Error
|
||||||
|
|
||||||
|
### Security Standards
|
||||||
|
|
||||||
|
#### Authentication
|
||||||
|
- **JWT-like**: Token based authentication
|
||||||
|
- **Secure storage**: localStorage için güvenlik
|
||||||
|
- **Token rotation**: Session management
|
||||||
|
- **Logout**: Proper token cleanup
|
||||||
|
|
||||||
|
#### Authorization
|
||||||
|
- **Role-based**: Access control by role
|
||||||
|
- **Route-level**: Middleware protection
|
||||||
|
- **Resource-level**: Ownership validation
|
||||||
|
- **API-level**: Permission checks
|
||||||
|
|
||||||
|
#### Data Validation
|
||||||
|
- **Input validation**: All user inputs
|
||||||
|
- **SQL injection**: Parameterized queries
|
||||||
|
- **XSS prevention**: Output escaping
|
||||||
|
- **CSRF protection**: Token validation
|
||||||
|
|
||||||
|
### Performance Standards
|
||||||
|
|
||||||
|
#### Frontend
|
||||||
|
- **Lazy loading**: Component lazy loading
|
||||||
|
- **Code splitting**: Dynamic imports
|
||||||
|
- **Bundle optimization**: Vite optimization
|
||||||
|
- **Asset optimization**: Image compression
|
||||||
|
|
||||||
|
#### Backend
|
||||||
|
- **Connection pooling**: Database connections
|
||||||
|
- **Query optimization**: Efficient queries
|
||||||
|
- **Caching**: Response caching
|
||||||
|
- **Compression**: Gzip compression
|
||||||
|
|
||||||
|
#### Database
|
||||||
|
- **Indexing**: Proper indexes
|
||||||
|
- **Query optimization**: Efficient queries
|
||||||
|
- **Connection management**: Single connection
|
||||||
|
- **Backup strategy**: Regular backups
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Not**: Bu yapı geliştirme sürecinde evrilebilir. Değişiklikler için ekibin onayı gerekir.
|
||||||
Reference in New Issue
Block a user