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