From 63abf6eaffe7cfef2867e462d2565eb0a6dbf61e Mon Sep 17 00:00:00 2001 From: szbk Date: Mon, 3 Nov 2025 23:12:45 +0300 Subject: [PATCH] Readme index'ler eklendi. --- .serena/.gitignore | 1 + .serena/project.yml | 84 +++++ README.md | 191 +++++++++++ data/app.db | Bin 49152 -> 49152 bytes docs/API.md | 659 +++++++++++++++++++++++++++++++++++++ docs/DATABASE.md | 438 ++++++++++++++++++++++++ docs/DEPLOYMENT.md | 729 ++++++++++++++++++++++++++++++++++++++++ docs/FRONTEND.md | 731 +++++++++++++++++++++++++++++++++++++++++ docs/KNOWLEDGE_BASE.md | 605 ++++++++++++++++++++++++++++++++++ docs/STRUCTURE.md | 429 ++++++++++++++++++++++++ 10 files changed, 3867 insertions(+) create mode 100644 .serena/.gitignore create mode 100644 .serena/project.yml create mode 100644 README.md create mode 100644 docs/API.md create mode 100644 docs/DATABASE.md create mode 100644 docs/DEPLOYMENT.md create mode 100644 docs/FRONTEND.md create mode 100644 docs/KNOWLEDGE_BASE.md create mode 100644 docs/STRUCTURE.md diff --git a/.serena/.gitignore b/.serena/.gitignore new file mode 100644 index 0000000..14d86ad --- /dev/null +++ b/.serena/.gitignore @@ -0,0 +1 @@ +/cache diff --git a/.serena/project.yml b/.serena/project.yml new file mode 100644 index 0000000..e0cd182 --- /dev/null +++ b/.serena/project.yml @@ -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: [] diff --git a/README.md b/README.md new file mode 100644 index 0000000..1824ff0 --- /dev/null +++ b/README.md @@ -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 +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. \ No newline at end of file diff --git a/data/app.db b/data/app.db index 31e07757a1a6ed35e39f7c0fe6f1ac34ad1b4532..ef847c4655f1ea0576d99b03d72e33956a2e955b 100644 GIT binary patch delta 57 zcmZo@U~Xt&o*>PbGf~EwF=t~!ggv9dN_I8nx#F>qr-ggvAB +``` + +**Yanıt (200):** +```json +{ + "message": "Oturum kapatildi." +} +``` + +### GET /session +Mevcut oturum bilgilerini getirme. + +**Headers:** +``` +X-Session-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: '' + } +}); +``` + +### 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. \ No newline at end of file diff --git a/docs/DATABASE.md b/docs/DATABASE.md new file mode 100644 index 0000000..abe99a4 --- /dev/null +++ b/docs/DATABASE.md @@ -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. \ No newline at end of file diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md new file mode 100644 index 0000000..1229616 --- /dev/null +++ b/docs/DEPLOYMENT.md @@ -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 +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 +(): + +# Ö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 . + +# 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 + +# 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. \ No newline at end of file diff --git a/docs/FRONTEND.md b/docs/FRONTEND.md new file mode 100644 index 0000000..71f947f --- /dev/null +++ b/docs/FRONTEND.md @@ -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 +
+
+ +
+
+ {#if user} + + {#if user.role === 'admin'} + + {:else if user.role === 'fuel_manager'} + + {:else if user.role === 'inventory_manager'} + + {:else} + + {/if} + {:else} + + {/if} +
+
+``` + +### 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'} + +{:else if user.role === 'fuel_manager'} + +{:else if user.role === 'inventory_manager'} + +{:else} + +{/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'} + Loading...}> + + +{/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. \ No newline at end of file diff --git a/docs/KNOWLEDGE_BASE.md b/docs/KNOWLEDGE_BASE.md new file mode 100644 index 0000000..51cde85 --- /dev/null +++ b/docs/KNOWLEDGE_BASE.md @@ -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 +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'} + Loading...}> + + +{/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. \ No newline at end of file diff --git a/docs/STRUCTURE.md b/docs/STRUCTURE.md new file mode 100644 index 0000000..306da17 --- /dev/null +++ b/docs/STRUCTURE.md @@ -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. \ No newline at end of file