ADMIN — SİSTEM YÖNETİMİ
Tüm ERP’nin kontrol merkezi. Kullanıcı kimlikleri, yetkiler, kimlik doğrulama, yazıcı donanımı, yazdırma kuyruğu izleme, AI asistan yapılandırması ve aktivite denetimi — sistemi güvenli, yapılandırılmış ve gözlemlenebilir tutan her şey.
Admin, kapı bekçisi ve kontrol odasıdır. Herhangi bir operatör QR kod tarayabilmeden, herhangi bir lab kullanıcısı bir testi onaylayabilmeden, herhangi bir mühendis kablo tasarlayabilmeden önce — bu modülde doğru yetkilerle bir kullanıcı olarak var olmaları gerekir. Admin, sisteme kimin erişebileceğini, içeri girdikten sonra ne yapabileceklerini, nasıl kimlik doğrulaması yapacaklarını ve sistemin hangi donanımla konuşacağını tanımlar. Rol tabanlı erişimi (super_admin, lab_user, operator) JSON olarak saklanan ultra-granüler sayfa-ve-buton düzeyinde yetkilerle birleştiren hibrit bir yetki sistemi yönetir. Fabrikanın etiket yazıcılarını kontrol eder, yazdırma kuyruğunu gerçek zamanlı izler ve AI asistan için tam bir yapılandırma arayüzü sağlar. Her kullanıcının her eylemi bir denetim izine kaydedilir. Bu modül olmadan kimse giriş yapamaz, hiçbir etiket yazdırılamaz ve hiçbir yetki uygulanamaz.
TABLE OF CONTENTS
1. ADMIN NE YAPAR
Admin modülü, tüm ERP sisteminin bağlı olduğu altı soruyu yanıtlar:
| Soru | Kim Yanıtlar | Nasıl |
|---|---|---|
| Sistemi kim kullanabilir? | Kullanıcı Yönetimi | Rol atamasıyla kullanıcı hesapları oluştur/düzenle/askıya al/sil |
| Her kullanıcı ne yapabilir? | Yetki Sistemi | Hibrit rol tabanlı + granüler sayfa.buton JSON yetkileri |
| Kullanıcılar kimliklerini nasıl kanıtlar? | Kimlik Doğrulama | Kullanıcı adı/şifre → JWT erişim + yenileme token’ları ve oturum takibi |
| Hangi yazıcılar var ve nerede? | Yazıcı Yönetimi | IP, port, malzeme atamaları, bağlantı testi ile ağ yazıcı kaydı |
| Yazdırma kuyruğunda ne oluyor? | Yazdırma İzleme | 4 yazıcı genelinde tüm yazdırma işlerinin gerçek zamanlı panosu, yeniden deneme/iptal |
| AI asistan nasıl yapılandırılır? | AI Ayarları | Çoklu sağlayıcı API anahtar yönetimi, model seçimi, denetim günlüğü |
1.1 Üç Kullanıcı Tipi
Sistem, her biri farklı erişim kapsamına ve farklı fiziksel kullanım bağlamına sahip üç temel kullanıcı tipi tanır:
Super Admin
Tam sistem erişimi. Kullanıcıları yönetebilir, yazıcıları yapılandırabilir, AI ayarlarını değiştirebilir, aktivite günlüklerini görüntüleyebilir ve her modüle erişebilir. Bu, fabrika müdürü veya IT yöneticisidir. Genellikle ofiste masaüstü bilgisayardan çalışır.
Lab Kullanıcısı
Lab panosu, test yönetimi, kalite kontrol, uyarı yönetimi ve test raporları. Ayrıca yazıcı bağlantılarını test edebilir ve başarısız yazdırma işlerini yeniden deneyebilir. Bu, laboratuvarda çalışan kalite mühendisidir. Genellikle lab’a özel bir iş istasyonundan çalışır.
Operatör
Makine operasyonu, üretim formları, malzeme tarama, temel pano ve iş emri görüntüleme. Bu, fabrika zemininde çalışan işçidir. Genellikle üretim hattının yanına monte edilmiş bir kiosk telefondan çalışır — bu yüzden operatör hesapları standart 12 saatlik süre yerine 6 aylık JWT token alır.
1.2 Hibrit Yetki Modeli
Yetki sistemi aynı anda iki katmanda çalışır:
Katman 1 — Rol Tabanlı (Eski): Kullanıcı kaydındaki user_type alanı. is_permitted_user(user, ["super_admin", "lab_user"]) ile kontrol edilir. Bu kaba filtredir: “en azından lab kullanıcısı mısın?”
Katman 2 — Granüler (Modern): Kullanıcı kaydındaki permissions JSON alanı. check_user_permission(user, page_id, button_id) ile kontrol edilir. Bu ince filtredir: “Hammaddeler Listesi sayfasında Sil butonuna tıklayabilir misin?”
Her iki katman, check_permission_smart adında geriye uyumlu bir fonksiyon aracılığıyla bir arada bulunur. Önce eski rol tabanlı sistemi kontrol eder, sonra granüler JSON sistemine düşer. Super admin’ler her ikisini de atlar — her zaman geçerler.
1.3 Kullanıcı Yönetiminin Ötesinde
Admin sadece kullanıcılarla ilgili değildir. Fiziksel donanımı (fabrika zeminindeki ağ yazıcıları) yöneten, gerçek zamanlı operasyonel izleme (yazdırma kuyruğu panosu) sağlayan ve diğer kullanıcıların etkileşimde bulunduğu AI asistanı kontrol eden tek modüldür. Ayrıca user_activity_logs tablosuna yazan tek modüldür ve sistemde alınan her yönetimsel eylemin denetim izini oluşturur.
2. VERİ AKIŞI
Admin’in veri akışları, Hammadde veya Teknik gibi üretim modüllerinden temelden farklıdır. Bu modüllerin doğrusal bir hattı vardır (tedarikçi → sipariş → giriş → envanter). Admin ise bir göbek-ve-kol (hub-and-spoke) desenine sahiptir: merkezde oturur ve diğer her modül ona bağlıdır.
2.1 Kimlik Doğrulama Akışı
Bundan sonraki tüm sistemdeki her API çağrısı, Authorization: Bearer başlığında JWT erişim token’ını taşır. Token, kullanıcının ID’sini, kullanıcı adını, user_type’ını ve yetkilerini içerir — bu da her modüldeki her route’un ek bir veritabanı sorgusu olmadan kimliği doğrulayabileceği ve yetkileri kontrol edebileceği anlamına gelir.
2.2 Yetki Uygulama Akışı
Önyüzde aynı kontrol proaktif olarak çalışır: route’lar menüden gizlenir, butonlar devre dışı bırakılır veya görünmez yapılır ve doğrudan URL erişimi denenirse tüm sayfalar kullanıcının izin verilen panosuna yönlendirilir.
2.3 Yazdırma İşi Akışı
Yazdırma işleri diğer modüller tarafından oluşturulur (Hammadde Girişi teslimat kaydettikten sonra QR etiketleri yazdırır, Hammaddeler Listesi talep üzerine etiket yeniden yazdırır) ancak kuyruğun kendisi Admin’de yaşar. Yazdırma İzleme, super admin’lere dört fabrika yazıcısındaki tüm işlerin gerçek zamanlı görünümünü, başarısız işleri yeniden deneme ve kuyruktakileri iptal etme yeteneğiyle sağlar.
2.4 AI Etkileşim Akışı
Her AI etkileşimi kapsamlı olarak günlüğe kaydedilir: kullanıcının sorgusu, algılanan dil, kullanılan AI modeli, akıl yürütme adımları, araç çağrıları, API yanıtları, zamanlama metrikleri ve güvenlik bayrakları. Bu, AI’nın ne yaptığının ve nedeninin tam bir adli izini oluşturur.
2.5 Göbek-ve-Kol Bağımlılığı
Sistemdeki her modül bir koldur; Admin göbektir. Hammadde, her API çağrısında kullanıcı kimlik doğrulaması için, QR etiketleri yazdırırken yazıcı erişimi için ve her buton tıklamasında yetki kontrolü için Admin’e ihtiyaç duyar. Teknik, operatör kayıtları ve kullanıcı kimliği için Admin’e ihtiyaç duyar. Üretim, Lab, Siparişler — hepsi her istekte get_current_user_dependency’yi çağırır ve bu, Admin’in verdiği JWT token’ını çözer. Admin çökerse, tüm sistem kilitlenir.
3. VERİTABANI KATMANI
Admin modülü 10 veritabanı tablosuna sahiptir, bu diğer tüm modüllerden fazladır. Bu tablolar dört gruba ayrılır: kimlik, oturumlar, donanım ve denetim.
3.1 Kimlik Tabloları
| Tablo | Amaç | Anahtar Sütunlar | İlişkiler |
|---|---|---|---|
users |
Sistemdeki her kişinin temel kimliği | id, username (unique), email (unique), hashed_password, user_type, status, is_active, is_superuser, permissions (JSON text), force_password_change, last_login, preferred_interface, device_info | 1—N user_sessions, 0..1 super_admins, 0..1 lab_users, 0..1 operators |
super_admins |
Super admin kullanıcılar için ek veriler | id, user_id (FK, unique), admin_level, permissions (JSON), access_logs (JSON) | N—1 users |
lab_users |
Laboratuvar kullanıcıları için ek veriler | id, user_id (FK, unique), lab_department, certifications (JSON), test_specializations (JSON), shift_schedule (JSON) | N—1 users |
operators |
Fabrika zemini operatörleri için ek veriler | id, user_id (FK, unique), assigned_machines (JSON), shift_schedule (JSON), skill_level, certifications (JSON) | N—1 users |
user_roles |
Yeniden kullanılabilir yetki şablonları | id, name (unique), description, permissions (JSON text), is_system (silmeyi engeller) | Bağımsız (şablon deposu) |
Kalıtım Deseni: Sistem, nullable sütunlu tek tablo kalıtımı yerine bir birleşik tablo deseni kullanır. users tablosu ortak alanları (giriş bilgileri, durum, yetkiler) tutar. Uzantı tabloları (super_admins, lab_users, operators), users.id’ye unique FK aracılığıyla tipe özel alanları tutar. Bu, temel users tablosunu yalın tutarken her kullanıcı tipinin özel veri depolamasına izin verir (örn. operatörlerin assigned_machines’i, lab kullanıcılarının certifications’ı vardır).
3.2 Oturum Tablosu
| Tablo | Amaç | Anahtar Sütunlar | İlişkiler |
|---|---|---|---|
user_sessions |
Aktif ve geçmiş giriş oturumları | id, user_id (FK), session_token (unique, indexed), refresh_token (unique, indexed), login_time, logout_time, expires_at, ip_address (IPv6-ready, 45 chars), user_agent, device_type, status | N—1 users (cascade delete) |
Oturumlar sadece token doğrulama için değildir. Tam bir giriş geçmişi sağlarlar: hangi cihaz kullanıldı, hangi IP’den, ne zaman giriş yapıldı, ne zaman çıkış yapıldı (veya oturum süresi doldu mu). users ilişkisindeki cascade delete, bir kullanıcıyı silmenin tüm oturumlarını otomatik olarak temizlemesi anlamına gelir.
3.3 Donanım Tabloları
| Tablo | Amaç | Anahtar Sütunlar | İlişkiler |
|---|---|---|---|
printers |
Fabrika zeminindeki ağ etiket yazıcıları | id, name, description, ip_address, port (default 9100), status (ONLINE/OFFLINE/ERROR/MAINTENANCE), is_active, assigned_materials (JSON array), location, last_checked | Standalone |
print_jobs |
Etiket yazdırma iş kuyruğu ve geçmişi | id, material_id (FK → raw_materials), qr_code, printer_id (1–4), copies, status (QUEUED/PRINTING/COMPLETED/FAILED/CANCELLED), retry_count, error_message, requested_by (FK → users), requested_at, started_at, completed_at, material_type, lot_number, supplier_name | N—1 raw_materials, N—1 users |
Görüntüleme için denormalize: print_jobs tablosu, material_type, lot_number ve supplier_name’i malzeme kaydından denormalize kopyalar olarak saklar. Bu, Yazdırma İzleme’nin raw_materials veya suppliers’a join yapmadan iş geçmişini görüntüleyebilmesi anlamına gelir — sık yenilenen gerçek zamanlı bir izleme panosu için kritiktir.
3.4 Denetim Tabloları
| Tablo | Amaç | Anahtar Sütunlar | İlişkiler |
|---|---|---|---|
user_activity_logs |
Tüm admin eylemlerinin denetim izi | id, user_id (FK, indexed), username (denormalized), action, module, target_type, target_id, details (JSON), ip_address, user_agent, created_at (indexed) | N—1 users |
ai_audit_logs |
Kapsamlı AI etkileşim adli analizi | id, user_id, username, user_type, session_id, ip_address, device_type, browser, os, original_query, query_language, ai_model, ai_reasoning, ai_confidence, selected_tool, tool_params, api_endpoint, api_response_status, success, error_type, total_duration_ms, ai_processing_ms, security_flags, was_blocked, block_reason, created_at | Standalone (47 columns) |
AI denetim tablosu tüm sistemdeki en geniş tablodur — 47 sütun. Bu kasıtlıdır. Her AI etkileşimi çok adımlı bir hattır (sorgu ayrıştırma → araç seçimi → API çağrısı → yanıt üretimi) ve her adım hata ayıklama veya güvenlik incelemesi için gerekebilecek veri üretir. Tablo, tam tablo taraması olmadan analitik sorguları desteklemek için (user_id, created_at), (selected_tool, created_at), (success, created_at) ve (ip_address, created_at) üzerinde bileşik indekslere sahiptir.
3.5 Varlık-İlişki Özeti
| İlişki | Tip | Kademeli Silme |
|---|---|---|
| users → user_sessions | 1—N | Delete (kullanıcı silinince oturumlar temizlenir) |
| users → super_admins | 1—0..1 | Yok (uzantı tablosu) |
| users → lab_users | 1—0..1 | Yok (uzantı tablosu) |
| users → operators | 1—0..1 | Yok (uzantı tablosu) |
| users → user_activity_logs | 1—N | Yok (loglar kullanıcı silinse de kalır) |
| users → print_jobs (requested_by) | 1—N | Yok |
| raw_materials → print_jobs (material_id) | 1—N | Yok (çapraz modül FK) |
4. BACKEND MİMARİSİ
Admin backend’i beş route grubu, bir temel servis, bir güvenlik modülü ve bir yetki yardımcı katmanı olarak organize edilmiştir. Tek bir route dosyasına sahip üretim modüllerinin aksine, Admin birden fazla dosyaya yayılır çünkü sorumlulukları birbirinden temelden farklıdır.
4.1 Route Grupları
| Route Grubu | Önek | Endpoint | Auth Gerekli | Min. Rol |
|---|---|---|---|---|
| Kimlik Doğrulama | /api/auth | 5 | Karışık (login herkese açık) | Yok / Herhangi |
| Kullanıcı Yönetimi | /api/user-management | 9 | Evet | Super Admin (çoğu), Herhangi (operatör listesi) |
| Yazıcılar | /api/printers | 5 | Evet | Super Admin (CRUD), Lab User (test) |
| Yazdırma Kuyruğu | /api/print-queue | 5 | Evet | Herhangi (kuyruk), Super Admin (yönetim) |
| AI | /api/ai | 12 | Evet | Herhangi (sohbet), Super Admin (yapılandırma) |
4.2 Kimlik Doğrulama Endpoint’leri (5)
| Metod | Yol | Amaç | Temel Davranış |
|---|---|---|---|
| POST | /auth/login | Kullanıcı girişi | Kullanıcı adı/şifre + device_type + remember_me kabul eder. access_token, refresh_token, expires_in, user objesi döndürür. Oturum kaydı oluşturur. |
| POST | /auth/logout | Oturumu sonlandır | Oturum durumunu “terminated” yapar, logout_time damgalar. |
| POST | /auth/refresh | Erişim token’ı yenile | refresh_token’ı doğrular, yeni access_token üretir. Refresh token’ı döndürmez. |
| GET | /auth/me | Mevcut kullanıcı bilgisi | JWT’yi çözer, ayrıştırılmış yetkilerle tam kullanıcı objesi döndürür. |
| GET | /auth/health | Sağlık kontrolü | Durum + veritabanı bağlantı kontrolü döndürür. |
4.3 Kullanıcı Yönetimi Endpoint’leri (9)
| Metod | Yol | Amaç | Temel Davranış |
|---|---|---|---|
| GET | /user-management/users/list | Tüm kullanıcıları listele | status_filter ve user_type sorgu parametrelerini destekler. Yetkileri JSON string’den objeye ayrıştırır. |
| GET | /user-management/operators | Operatörleri listele | Sadece aktif operatörleri döndürür. Tüm kimliği doğrulanmış kullanıcılara açıktır (üretim modülleri için gerekli). |
| POST | /user-management/users/create | Kullanıcı oluştur | Sağlanmazsa şifreyi otomatik üretir. force_password_change ayarlar. Aktivite günlüğüne kaydeder. |
| PUT | /user-management/users/{id} | Kullanıcı güncelle | Kısmi güncelleme: username, email, full_name, user_type, status, is_active, permissions, password. |
| POST | /user-management/users/{id}/suspend | Askıya al/aç | “active” ve “suspended” durumları arasında geçiş yapar. Aktivite günlüğüne kaydeder. |
| DELETE | /user-management/users/{id} | Kullanıcıyı kalıcı sil | Kalıcı silme. Kendini silmeyi engeller (kendi hesabınızı silemezsiniz). |
| POST | /user-management/users/{id}/reset-password | Şifre sıfırlamayı zorla | Güvenli 12 karakterli rastgele şifre üretir (harf + rakam + sembol). force_password_change=True ayarlar. |
| GET | /user-management/roles/list | Rol şablonlarını listele | Yetki şablonu atamasında kullanılmak üzere tüm UserRole kayıtlarını döndürür. |
| GET | /user-management/activity-logs | Aktivite günlüğü görüntüleyici | user_id, module, action’a göre filtrelemeyi destekler. Varsayılan limit 200. |
4.4 Yazıcı & Yazdırma Kuyruğu Endpoint’leri (10)
| Metod | Yol | Amaç | Temel Davranış |
|---|---|---|---|
| GET | /printers/list | Yazıcıları listele | Opsiyonel active_only filtresi. |
| POST | /printers/create | Yazıcı ekle | Ad, IP, port (varsayılan 9100), konum, assigned_materials (JSON dizisi). |
| PUT | /printers/update/{id} | Yazıcı düzenle | Tüm alanlar güncellenebilir. |
| POST | /printers/{id}/test | Bağlantı testi | Yazıcı IP:port’a ağ bağlantısı dener. Durumu ONLINE veya OFFLINE olarak günceller. |
| DELETE | /printers/{id} | Yazıcı kaldır | Silmeye izin vermeden önce bekleyen yazdırma işlerini kontrol eder. |
| POST | /print-queue/queue/{material_id} | Etiket yazdırmayı kuyruğa ekle | Malzeme ve talep eden kullanıcıya bağlı QUEUED iş oluşturur. Yazıcı sorgu parametresiyle seçilir (1–4). |
| GET | /print-queue/jobs | İş geçmişi | status, printer_id’ye göre filtrelenebilir. Maksimum 500 sonuç. |
| POST | /print-queue/jobs/{id}/retry | Başarısız işi yeniden dene | Durumu QUEUED’a sıfırlar, retry_count’u artırır. |
| DELETE | /print-queue/jobs/{id} | İşi iptal et | Sadece QUEUED işler iptal edilebilir (PRINTING değil). |
| GET | /print-queue/stats | Kuyruk istatistikleri | Sayıları döndürür: queued, printing, completed, failed. |
4.5 AI Endpoint’leri (12)
| Metod | Yol | Amaç | Temel Davranış |
|---|---|---|---|
| POST | /api/ai/chat | AI sorgusu gönder | Ana sohbet endpoint’i. Sorguyu işler, araçları çağırır, yanıt döndürür. |
| GET | /api/ai/status | Servis durumu | AI servis sağlığı ve yapılandırma durumunu döndürür. |
| GET | /api/ai/models | Mevcut modeller | Sağlayıcılar genelinde desteklenen tüm AI modellerini listeler. |
| POST | /api/ai/reset | AI ajanını sıfırla | Konuşma bağlamını temizler ve ajan durumunu sıfırlar. |
| GET | /api/ai/config | Yapılandırmayı getir | Mevcut değerleri döndürür: enabled bayrağı, model_name, max_tokens, temperature. |
| POST | /api/ai/config | Yapılandırmayı kaydet | AI ayarlarını günceller. Sadece super admin. |
| GET | /api/ai/stats | Kullanım istatistikleri | Sorgu sayıları, başarı oranları, ortalama yanıt süreleri. |
| GET | /api/ai/audit-logs | Denetim günlüğü görüntüleyici | Sayfalanmış (limit + offset). Tam etkileşim adli analizini döndürür. |
| GET | /api/ai/api-keys/status | API anahtar durumu | Her sağlayıcı için maskeli anahtar durumunu döndürür (örn. “sk-***...abc”). |
| POST | /api/ai/api-keys/save | API anahtarı sakla | .env dosyasına yazar. Gemini, OpenAI, Anthropic destekler. Yanıtta maskeler. |
| DELETE | /api/ai/api-keys/{provider} | API anahtarı kaldır | .env dosyasından anahtarı kaldırır. |
| POST | /api/ai/api-keys/test/{provider} | API anahtarını test et | Anahtarın çalıştığını doğrulamak için hafif bir API çağrısı yapar. |
4.6 Temel Servisler
AuthenticationService
Merkezi kimlik doğrulama motoru. Beş operasyon yürütür:
- authenticate_user — Kullanıcıyı kullanıcı adı veya e-posta ile bulur, şifreyi bcrypt ile doğrular,
last_loginzaman damgasını günceller. - create_user_session — JWT erişim ve yenileme token’ları üretir. Kritik detay: operatör hesapları 6 aylık token süresi alır (yeniden giriş gerektirmemesi gereken kiosk telefonlar için), diğer tüm hesaplar standart 12 saatlik süre alır.
- get_user_by_token — JWT’yi çözer, süre dolumunu doğrular, kullanıcının hala var olup olmadığını ve aktif olup olmadığını kontrol eder.
- logout_user — Oturum kaydını sonlandırır, çıkış zamanını damgalar.
- refresh_token — Yenileme token’ını doğrular, yeni bir oturum oluşturmadan yeni erişim token’ı verir.
SecurityManager
Düşük seviye kriptografik operasyonlar: bcrypt şifre hashleme ve doğrulama, yapılandırılabilir süreli JWT oluşturma, imza doğrulamalı JWT çözme ve token süre dolumu doğrulama. Yapılandırılabilir gizli anahtar ile HS256 algoritması kullanır.
Yetki Yardımcıları
Sistemdeki her modül tarafından kullanılan yetki kontrol omurgasını oluşturan dört fonksiyon:
is_permitted_user(user, required_types)— Eski rol kontrolü. Super admin her zaman geçer.check_user_permission(user, page_id, button_id)— Granüler JSON yetki kontrolü. Kullanıcınınpermissionsalanını ayrıştırır,pages[page_id].buttons[button_id]’ye gider.has_special_permission(user, permission)—hard_deleteveyamanage_usersgibi özel bayrakları kontrol eder.check_permission_smart(user, required_types, page_id, button_id)— Birleşik giriş noktası. Önce rol tabanlıyı dener, sonra granülere düşer. Çoğu route’un gerçekte çağırdığı budur.
4.7 FastAPI Bağımlılıkları
Admin, sistemdeki her modülün içe aktardığı dört enjekte edilebilir bağımlılık tanımlar:
| Bağımlılık | Ne Yapar | Kullanan |
|---|---|---|
get_current_user_dependency | Authorization başlığındaki JWT token’dan kullanıcıyı çıkarır ve doğrular | Sistemdeki her kimliği doğrulanmış endpoint |
require_super_admin | user_type “super_admin” değilse 403 fırlatır | Admin CRUD operasyonları, sistem yapılandırması |
require_lab_user | user_type “lab_user” veya “super_admin” değilse 403 fırlatır | Lab test route’ları, kalite kontrol |
require_operator | user_type “operator” veya üstü değilse 403 fırlatır | Üretim route’ları, malzeme tarama |
Admin, güvenlik katmanını içe aktarılabilir bağımlılıklar olarak dışa aktarır. Bu, Admin’i göbek yapan mimari mekanizmadır: diğer modüller kendi kimlik doğrulamalarını uygulamaz — Admin’den get_current_user_dependency’yi içe aktarır ve FastAPI Depends() parametresi olarak kullanırlar. Tek doğruluk kaynağı, sıfır tekrar.
5. ÖNYÜZ
Admin önyüzü, beş ayrı sayfa ile tüm uygulamadaki her sayfayı etkileyen kesmesel bir yetki katmanından oluşur.
5.1 Sayfa Envanteri
| Sayfa | Route | Bileşen | Erişim |
|---|---|---|---|
| Giriş | /user/login | src/pages/user/login/index.tsx | Herkese açık (kimlik doğrulamasız) |
| Kullanıcı Yönetimi | /admin/user-management | src/pages/Admin/UserManagement/index.tsx | canAdmin |
| Yazıcı Yönetimi | /admin/printer-management | src/pages/Admin/PrinterManagement/index.tsx | canAdmin |
| Yazdırma İzleme | /admin/print-monitor | src/pages/Admin/PrintJobMonitor/index.tsx | canAdmin |
| AI Ayarları | /admin/ai-settings | src/pages/Admin/AISettings/index.tsx | canAdmin |
Dört admin sayfasının tümü /admin route öneki altında oturur ve görünürlüğü super admin kullanıcılarla sınırlayan canAdmin erişim korumasını paylaşır. Giriş sayfası, tüm uygulamadaki tek herkese açık sayfadır.
5.2 Yetki Katmanı (Kesmesel)
Admin’in önyüze en etkili katkısı kendi sayfaları değildir — diğer her sayfanın kullandığı yetki altyapısıdır. Bu üç dosyada yaşar:
access.ts
Dinamik erişim fonksiyonlarını tanımlar: canAdmin, canLab, canProduction, vb. Route yapılandırmasında erişim korumaları olarak referans verilir. Ayrıca kullanıcının ayrıştırılmış yetki JSON’ından okuyan canAccessPage(pageId) ve modül düzeyinde kontroller sağlar.
permissionManifest.ts
Sistemdeki her sayfanın ve her butonun statik kaydı. Sayfa kimliklerini (örn. admin.kullanici_yonetimi), buton kimliklerini (örn. create_user, delete_user), etiketleri, açıklamaları ve critical bayraklarını tanımlar. Kullanıcı Yönetimi tarafından yetki editörünü çizmek için kullanılır.
buttonRegistry.ts
Statik manifestin dinamik karşılığı. Bileşenler, mount sırasında butonlarını global bir kayıt defterine kaydeder. Bu, Kullanıcı Yönetimi yetki editörünün, manifest güncellenmemiş olsa bile çalışan uygulamada var olan butonları keşfetmesine olanak tanır.
Hibrit Keşif Deseni: Yetki sistemi hem statik bir manifest (tüm sayfaların ve butonların sabit kodlanmış listesi) hem de dinamik bir kayıt defteri (bileşenler çalışma zamanında kendilerini kaydeder) kullanır. Kullanıcı Yönetimi yetki editörü, yapılandırılmış ağaç görünümü için manifestten okur ancak dinamik olarak kaydedilmiş butonları da keşfedebilir. Bu, sistemdeki herhangi bir sayfaya eklenen yeni butonların, merkezi bir yapılandırma dosyasını manuel olarak güncellemeden yetki ataması için kullanılabilir hale gelmesi anlamına gelir.
5.3 Giriş Sayfası
Giriş sayfası üç senaryoyu yönetir:
- Standart giriş: “Beni hatırla” onay kutusuyla kullanıcı adı/şifre formu. JWT token’larını ve kullanıcı verilerini
localStorage’da saklar (solen_auth_token,solen_refresh_token,solen_current_user). - Kiosk otomatik giriş: Fully Kiosk Browser’ı user agent string’i üzerinden algılar. Algılandığında, otomatik olarak operatör hesabıyla giriş yapar ve
/production’a yönlendirir. İnsan etkileşimi gerekmez. - Gizli URL token’ı: Herhangi bir tarayıcıdan otomatik girişi tetiklemek için URL parametresi olarak
?kiosk=SOLEN_FACTORY_2024_KIOSK_SECRETkabul eder. Bu, yeni kiosk cihazlarının montajı için fabrika zemine özel bir kolaylıktır.
5.4 Kullanıcı Yönetimi Sayfası
Admin modülündeki en karmaşık sayfa. Üç sekmeli modal ile kullanıcı hesapları için tam bir CRUD arayüzü sağlar:
- Sekme 1 — Temel Bilgiler: Kullanıcı adı, e-posta, tam ad, kullanıcı tipi (super_admin, lab_user, operator, teknik_user, bakim_user ve özel tiplerle dropdown), durum, şifre (yeni kullanıcılar için), şifre değiştirmeyi zorla toggle’ı.
- Sekme 2 — Yetkiler: Granüler yetki editörü. Tam yetki manifestini bir ağaç olarak çizer: her sayfa bir switch (erişim açık/kapalı) ve her sayfa altında bireysel butonlar onay kutularıdır. Dört hızlı doldurma şablonu içerir: Tam, Boş, Operatör Varsayılan, Lab Kullanıcı Varsayılan.
- Sekme 3 — Önizleme: Kaydettikten sonra kullanıcının neye erişebileceğinin salt okunur özetini gösterir — hangi modüller, hangi sayfalar, hangi butonlar.
Modalın ötesinde sayfa şunları sağlar: kullanıcı adı/e-posta/tam ad üzerinden arama, user_type ve duruma göre filtreleme, şifre sıfırlama (yeni şifreyi üretir ve görüntüler), askıya al/etkinleştir toggle’ı, onaylamalı silme ve Turkey/Istanbul saat dilimi dönüştürmesiyle son giriş görüntüleme.
5.5 Yazıcı Yönetimi Sayfası
Fabrika etiket yazıcıları için CRUD arayüzü. Her yazıcının: ad, açıklama, IP adresi, port, konum, durum ve atanmış malzemeleri (malzeme tiplerinden çoklu seçim: raw_copper, raw_tin, raw_plastic, vb.) vardır. Yazıcının ağda erişilebilir olduğunu doğrulamak için backend’in /printers/{id}/test endpoint’ine ulaşan bir “Bağlantı Testi” butonu içerir.
5.6 Yazdırma İzleme Sayfası
Gerçek zamanlı izleme panosu. Üst bölüm dört istatistik kartı gösterir: Bekleyen (mavi), Yazdırılan (turuncu), Tamamlanan (yeşil), Başarısız (kırmızı). Altında sütunlarla tüm yazdırma işlerini gösteren bir ProTable vardır: QR kod, malzeme tipi, lot numarası, tedarikçi, yazıcı, durum, talep eden, talep tarihi, tamamlanma tarihi, hata mesajı. Yeniden deneme (başarısız işleri yeniden kuyruğa ekler) ve iptal (kuyruktaki işleri kaldırır) destekler. Tüm zaman damgaları Turkey/Istanbul saat dilimindedir.
5.7 AI Ayarları Sayfası
Dört sekmeli yapılandırma arayüzü:
- Genel Bakış: AI durumu (aktif/inaktif), bugünkü sorgu sayısı, toplam sorgular, ortalama yanıt süresi, başarı oranı görselleştirmesi ve bağlantı testi butonu.
- API Anahtarları: Üç sağlayıcı için (Gemini, OpenAI, Anthropic) API anahtarlarını kaydet, test et ve sil. Anahtarlar arayüzde maskelenir ve sunucunun .env dosyasında saklanır.
- Model Ayarları: AI’yı etkinleştir/devre dışı bırak, model seç (sağlayıcıya göre gruplandırılmış cascader: Gemini 3 Flash/Pro, GPT-5.2/Mini, Claude Sonnet/Opus/Haiku), maks token (1024–8192) ve sıcaklık (0.1–0.9) yapılandır.
- Denetim Günlüğü: AI etkileşimlerinin tam geçmişi. Orijinal sorguyu ve AI yanıtını gösteren genişletilebilir satırlı ProTable. Kullanıcı, araç, durum, IP adresine göre filtrelenebilir. Yanıt süresi metrikleri içerir.
5.8 Ortak Önyüz Desenleri
| Desen | Kullanım |
|---|---|
| ProTable (Ant Design Pro) | Her liste sayfası, yerleşik arama, filtreleme, sayfalama ve araç çubuğu özelleştirmesiyle ProTable kullanır. |
| ProConfigProvider trTR locale ile | Tüm tablolar ve formlar sütun başlıkları, araç çubuğu butonları ve boş durumlar için Türkçe metin gösterir. |
| PageContainer | Breadcrumb ve başlıklı tutarlı sayfa üst bilgileri. |
| Modal formlar | Oluşturma/Düzenleme operasyonları form doğrulamasıyla ortalanmış modal kullanır. |
| Durum Etiketleri | Durum görüntüleme için renk kodlu Ant Design Tag’ları (yeşil=aktif, kırmızı=askıda, mavi=bekleyen, vb.). |
| Turkey/Istanbul saat dilimi | Tüm zaman damgası görüntülemeleri toLocaleString() kullanarak Europe/Istanbul’a dönüştürülür. |
| message.success / message.error | Operasyon geri bildirimi için Ant Design bildirimleri, tamamı Türkçe. |
5.9 API Katmanı
Önyüz, dağıtım bağlamına göre backend URL’sini dinamik olarak çözen merkezi bir API yardımcısı (src/utils/api.ts) aracılığıyla backend ile iletişim kurar:
- HTTPS modu:
/apiproxy kullanır (reverse proxy yönlendirmeyi yönetir). - HTTP localhost:
http://localhost:8000/api(geliştirme). - HTTP yerel ağ:
http://{hostname}:8000/api(fabrika LAN erişimi). - Özel geçersizleme: Özel dağıtımlar için
window.BACKEND_URL.
Her API çağrısı, localStorage’dan alınan Authorization: Bearer {token} başlığını içerir. Kimlik doğrulama servisi (src/services/realAuth.ts), tüm sayfaların içe aktardığı login(), logout(), getCurrentUser() ve getToken() fonksiyonlarını sağlar.
6. ALT MODÜLLER
Admin modülü dört alt modül olarak organize edilmiştir, operasyonel akışa göre: yazdırma işleri izlenebilmeden önce yazıcılar yapılandırılmalı, AI ayarları bağımsız durur ve kullanıcı yönetimi her şeye erişimi yönetir.
Yazıcı Yönetimi (Printer Management)
Fabrika zeminindeki ağ etiket yazıcılarının kaydı ve yapılandırması. IP/port yapılandırması, malzeme tipi atamaları, bağlantı testi ve durum izleme.
Yazdırma İzleme (Print Job Monitor)
Dört yazıcı genelinde tüm etiket yazdırma işlerini izleyen gerçek zamanlı pano. Kuyruk istatistikleri, iş geçmişi, başarısızlıklar için yeniden deneme ve kuyruktaki işler için iptal.
AI Ayarları (AI Settings)
ERP’nin AI asistanı için yapılandırma arayüzü. Çoklu sağlayıcı API anahtar yönetimi, model seçimi, parametre ayarlama, kullanım istatistikleri ve her AI etkileşiminin kapsamlı denetim günlüğü.
Kullanıcı Yönetimi (User Management)
Kullanıcı hesaplarının tam yaşam döngüsü yönetimi: oluşturma, düzenleme, askıya alma, silme, şifre sıfırlama ve granüler yetki editörü. Sistemde kimin var olduğunu ve ne yapabileceğini tanımlar.
6.1 Yazıcı Yönetimi (Printer Management)
6.1.1 Amaç ve İş Bağlamı
Fabrikaya giren her hammadde, QR kodu, ağırlık, tedarikçi, lot numarası ve giriş tarihi içeren basılı bir A6 etiket alır. Bu etiketler malzemenin fiziksel kimliğidir — aşağı akıştaki her istasyonda (lab testi, üretim, stok) taranır. Etiket yazıcıları, belirli konumlara yerleştirilmiş endüstriyel ağ cihazlarıdır (TCP port 9100 / IPP port 631): laboratuvar ve üç üretim hattı. Yazıcı Yönetimi, bu fiziksel cihazların yapılandırıldığı, test edildiği ve malzeme türlerine atandığı kayıt defteridir.
Bu alt modül olmadan sistem yazdırma işlerini nereye göndereceğini bilemez. Dört soruyu yanıtlar: Hangi yazıcılar var? Neredeler? Çevrimiçiler mi? Her yazıcı hangi malzeme türlerini idare edebilir?
6.1.2 Veritabanı Şeması
Tek tablo: printers (model dosyası: 66 satır)
| Sütun | Tip | Kısıtlamalar | Amaç |
|---|---|---|---|
id | Integer PK | Otomatik artış, indeksli | Benzersiz yazıcı tanımlayıcı |
name | String(100) | NOT NULL | Okunabilir ad (örn. “Lab Yazıcısı”) |
description | Text | NULLABLE | İsteğe bağlı açıklama |
ip_address | String(50) | NOT NULL | Ağ IP adresi (örn. 192.168.0.182) |
port | Integer | NOT NULL, varsayılan 9100 | Ağ portu (RAW için 9100, IPP için 631) |
status | String(20) | NOT NULL, varsayılan “online” | Mevcut durum: online / offline / error / maintenance |
is_active | Boolean | NOT NULL, varsayılan True | Geçici etkinleştirme/devre dışı bırakma |
assigned_materials | Text | NULLABLE | Bu yazıcının idare ettiği malzeme tür kodlarının JSON dizisi (örn. ["raw_copper","raw_tin"]) |
location | String(100) | NULLABLE | Fiziksel konum (örn. “Laboratuvar”, “Üretim - Hat 1”) |
created_at | DateTime | NOT NULL, otomatik | Oluşturma zaman damgası |
updated_at | DateTime | NOT NULL, otomatik + onupdate | Son değişiklik zaman damgası |
last_checked | DateTime | NULLABLE | Son bağlantı testi zaman damgası |
PrinterStatus Enum
class PrinterStatus(str, Enum): ONLINE = "online" OFFLINE = "offline" ERROR = "error" MAINTENANCE = "maintenance"
Varsayılan Yazıcılar (Migration Tohum Verisi)
| ID | Ad | IP | Port | Konum | Atanmış Malzemeler |
|---|---|---|---|---|---|
| 1 | Lab Yazıcısı | 192.168.0.182 | 9100 | Laboratuvar | A, B, C, D, E, F (tüm türler) |
| 2 | Üretim Yazıcısı 1 | 192.168.0.183 | 9100 | Üretim - Hat 1 | [] (yok) |
| 3 | Üretim Yazıcısı 2 | 192.168.0.184 | 9100 | Üretim - Hat 2 | [] (yok) |
| 4 | Üretim Yazıcısı 3 | 192.168.0.185 | 9100 | Üretim - Hat 3 | [] (yok) |
6.1.3 API Sözleşmesi — 5 Endpoint
| Metot | Yol | Yetki | Ne Yapar |
|---|---|---|---|
GET | /api/printers/list | Kimlik doğrulanmış herkes | Tüm yazıcıları listeler. İsteğe bağlı ?active_only=true filtresi. assigned_materials’ı JSON’dan ayrıştırır. |
POST | /api/printers/create | Yalnızca super_admin | Yeni yazıcı oluşturur. Zorunlu: name, ip_address. Varsayılan port=9100, status=online, is_active=true. assigned_materials dizisini JSON string’e dönüştürür. |
PUT | /api/printers/update/{id} | Yalnızca super_admin | Yazıcıyı günceller. Kısmi güncelleme — yalnızca gönderilen alanlar değişir. updated_at damgalanr. |
POST | /api/printers/{id}/test | super_admin veya lab_user | CUPS lpstat -p ile bağlantı testi. status’ü online/offline olarak günceller ve last_checked damgalar. |
DELETE | /api/printers/{id} | Yalnızca super_admin | Yazıcıyı siler. Bekleyen işler (QUEUED veya PRINTING) varsa engellenir. Hata: “Bu yazıcının {n} bekleyen işi var.” |
6.1.4 CRUD Akışı
Oluştur:
- Araç çubuğunda “Yeni Yazıcı Ekle” butonuna tıkla
- Modal (600px) 7 alanla açılır: ad (zorunlu), açıklama, konum, IP adresi (zorunlu), port (varsayılan 9100), atanmış malzemeler (çoklu seçim: A=Bakır, B=Kalay, C=Plastik, D=Katalizör, E=Boya, F=Antirodent), durum
- Gönderimde:
POST /api/printers/create - Backend
is_active=true,status=onlineile kayıt oluşturur, assigned_materials dizisini JSON string’e dönüştürür - Başarıda: toast “Yazıcı ‘{ad}’ eklendi” → modal kapanır → tablo yenilenir
- Not: Yeni yazıcının arka plan yazdırma işçisinin başlaması için uygulama yeniden başlatılmalıdır
Oku:
- Sayfa yüklenir →
GET /api/printers/list - ProTable (11 sütun) render eder: ID, ad, açıklama, IP (mavi etiket), port, konum, durum (renk kodlu etiket), atanmış malzemeler (harf etiketleri), aktif (onay/çarpı ikon), işlemler
- İstemci tarafı arama, ad, açıklama, IP, konum, durum, port ve ID üzerinde aynı anda filtreler
Güncelle:
- İşlemler sütunundaki düzenle ikonuna tıkla
- Aynı modal mevcut değerlerle dolu olarak açılır
- Alanları değiştir → “Güncelle”ye tıkla
PUT /api/printers/update/{id}→ backend yalnızca gönderilen alanları günceller,updated_atdamgalar- Başarıda: toast “Yazıcı ‘{ad}’ güncellendi” → modal kapanır → tablo yenilenir
Sil:
- İşlemler sütunundaki sil ikonuna (tehlike butonu) tıkla
- Onay modalı: “{ad} yazıcısını silmek istediğinize emin misiniz?”
- Onayda:
DELETE /api/printers/{id} - Backend bekleyen yazdırma işlerini (QUEUED veya PRINTING durumu) kontrol eder
- Bekleyen işler varsa: silme engellenir, hata “Bu yazıcının {n} bekleyen işi var. Önce işleri tamamlayın veya iptal edin.”
- Bekleyen iş yoksa: yazıcı silinir → toast → tablo yenilenir
Bağlantı Testi:
- İşlemler sütunundaki test ikonuna (ApiOutlined) tıkla
POST /api/printers/{id}/test- Backend
PrintService.test_printer_connection()çağırır, alt süreç üzerindenlpstat -p {yazıcı_adı}çalıştırır - Olası sonuçlar: “connected” (boşta), “busy”, “not_found”, “timeout”, “error”
- Backend
printer.status’ü (ONLINE veya OFFLINE) velast_checked’ı günceller - Başarıda: yazıcı adıyla toast → tablo yenilenir (durum sütunu yeni durumu yansıtır)
- Başarısızlıkta: uyarı mesajı → tablo yenilenir (durum “Çevrimdışı” kırmızı görünür)
6.1.5 Yazdırma Servisi — Etiket Üretim Motoru
Dosya: app/services/print_service.py (576 satır). A6 etiketleri üreten ve yazdıran çekirdek servis.
Etiket Özellikleri
| Özellik | Değer |
|---|---|
| Boyut | A6 (827 × 1165 piksel) |
| DPI | 200 |
| QR Kod Boyutu | 300px, ortalanmış, hata düzeltme seviyesi H |
| Saat Dilimi | Europe/Istanbul (Türkiye) |
| Yazdırma Protokolü | CUPS/IPP, lp komutu ile A6 medya + sayfaya sığdır |
| Zaman Aşımı | Yazdırma komutu başına 10 saniye |
Etiket İçerik Düzeni
- Ortalanmış QR kod (300px) ve altında QR metni
- Lot numarası (varsa)
- Ağırlık (kg)
- Malzeme türü / ürün adı
- Tarih ve saat (Türkiye saat dilimi)
- “Oluşturan” kullanıcı adı
- Notlar (varsa)
Temel Servis Metotları
| Metot | Ne Yapar |
|---|---|
generate_qr_code(data, size) | Hata düzeltme H ile QR kod görüntüsü oluşturur |
create_label_image(material_data) | PIL kullanarak QR, ağırlık, tedarikçi, lot, tarihlerle A6 etiket oluşturur |
print_via_cups(image, printer_name, copies) | Geçici PNG’ye kaydeder → A6 medya ile lp komutu → temizler |
print_label(material_data) | Üret + tek etiket yazdır (1 kopya) |
print_label_with_quantity(material_data, copies) | Üret + birden fazla kopya ile yazdır |
print_multiple_labels(materials) | Toplu yazdırma: başarı/başarısız sayılarıyla sıralı işleme |
get_label_preview(material_data) | Base64 kodlanmış etiket görüntüsü döndürür (yazdırma yok) |
test_printer_connection(printer_name) | lpstat -p alt süreci çalıştırır, connected/busy/not_found/timeout/error döndürür |
get_available_printers() | lpstat -p -d çalıştırır, mevcut CUPS yazıcılarını ayrıştırır |
Font Geri Dönüş Zinciri
Servis fontları platform sırasıyla dener: macOS (/System/Library/Fonts/) → Linux (/usr/share/fonts/) → Windows (C:/Windows/Fonts/) → PIL varsayılan. Bu, etiket üretiminin tüm geliştirme ve üretim ortamlarında çalışmasını sağlar.
6.1.6 Yazdırma İşçisi — Arka Plan İş İşleme
Dosya: app/services/print_worker.py (292 satır). Her aktif yazıcı kendine ait bir arka plan işçi thread’i alır.
Mimari
İşçi Yaşam Döngüsü
- Başlatma: IP’den CUPS yazıcı adı üretir (örn.
Printer_192_168_0_182), yazıcıyılpadminile CUPS’a kaydeder,lpoptionsile A6’yı varsayılan medya olarak ayarlar - Yoklama döngüsü: Her 1 saniyede bu yazıcı için sıradaki QUEUED işi sorgular (
requested_at’a göre sıralı — FIFO) - İş işleme: Durumu PRINTING yapar →
started_atdamgalar → malzeme + kullanıcı verisini çeker →print_label_with_quantity()çağırır - Başarıda: Durum → COMPLETED,
completed_atdamgalanır - Başarısızlıkta:
retry_count < 3ise: artır, QUEUED’a geri al.retry_count ≥ 3ise: durum → FAILED
CUPS Otomatik Kayıt
Bir işçi başladığında, yazıcı CUPS’a kayıtlı değilse işçi otomatik olarak ekler:
# Yazıcıyı CUPS’a otomatik kaydet
lpadmin -p Printer_192_168_0_182 -E -v ipp://192.168.0.182:631/ipp/print -m everywhere
lpoptions -p Printer_192_168_0_182 -o media=A6
6.1.7 Malzeme Atama Sistemi
Her yazıcıya assigned_materials JSON dizisi aracılığıyla belirli malzeme türleri atanabilir. Altı malzeme türü kodu, fabrikanın QR kod harf sistemine karşılık gelir:
| Kod | Harf | Malzeme |
|---|---|---|
raw_copper | A | Bakır |
raw_tin | B | Kalay |
raw_plastic | C | Plastik |
raw_catalyst | D | Katalizör |
raw_dye | E | Boya |
raw_antirodent | F | Antirodent |
Lab yazıcısı (ID 1) tüm malzeme girişlerini idare ettiği için altı türe de atanmıştır. Üretim yazıcılarının boş atamaları vardır — üretim aşaması etiketleme için kullanılırlar.
6.1.8 Frontend Mimarisi
Tek dosya: src/pages/Admin/PrinterManagement/index.tsx (527 satır). Rota: /admin/printer-management.
Bileşen Yapısı
ProTable (11 sütun)
ID (sabit sol), ad (sabit sol), açıklama, IP adresi (mavi etiket), port, konum, durum (renk kodlu etiket: yeşil=çevrimiçi, kırmızı=çevrimdışı, turuncu=hata, gri=bakımda), atanmış malzemeler (harf etiketleri), aktif (onay/çarpı ikon), işlemler (sabit sağ).
Ekle/Düzenle Modalı (600px)
7 form alanı: ad (zorunlu), açıklama (textarea), konum, IP adresi (zorunlu), port (sayı, varsayılan 9100), atanmış malzemeler (malzeme kodlarıyla çoklu seçim), durum (açılır liste: çevrimiçi/çevrimdışı/bakımda/hata).
Araç Çubuğu
Arama girdisi (tüm sütunlarda istemci tarafı filtreleme) + “Yeni Yazıcı Ekle” birincil buton. Tablo seçenekleri: yoğunluk, yenile, sütun ayarları.
İşlem Butonları (satır başına)
Bağlantı testi (ApiOutlined), Düzenle (EditOutlined), Sil (DeleteOutlined, tehlike). Sil, devam etmeden önce onay modalı gösterir.
İstemci Tarafı Arama
Arama girdisi tüm görünür sütunlarda aynı anda filtreler: ad, açıklama, IP adresi, konum, durum (İngilizce ve Türkçe terimler), port ve ID. Bu tamamen frontend filtrelemededir — tam veri seti her zaman çekilir.
WebSocket Entegrasyonu Yok
Diğer modüllerin aksine, Yazıcı Yönetimi gerçek zamanlı güncellemeler için WebSocket kullanmaz. Tablo yenilemeleri her mutasyondan (oluştur, güncelle, sil, test) sonra manuel actionRef.current?.reload() ile gerçekleşir.
6.1.9 Yetki Modeli
Sayfa ID: admin.yazici_yonetimi
| Yetki ID | Etiket | Açıklama | Kritik |
|---|---|---|---|
access_page | Sayfaya Erişim | Sayfayı görüntüleme | |
view_table | Tablo Görüntüle | Yazıcı tablosunu görme | |
create_printer | Yeni Yazıcı Ekle | Yeni yazıcı oluşturma | |
edit_printer | Yazıcı Düzenle | Yazıcı ayarlarını güncelleme | |
test_connection | Bağlantı Test | Yazıcı bağlantısını test etme | |
assign_materials | Malzeme Ata | Yazıcıya malzeme türlerini atama | |
delete_printer | Yazıcı Sil | Yazıcıyı silme | ● |
Backend rol tabanlı uygular: yalnızca super_admin oluşturabilir/güncelleyebilir/silebilir, super_admin + lab_user test edebilir. Frontend bu 7 granüler yetkiyi yetki editörünün keşfetmesi için buttonRegistry’ye kaydeder.
6.1.10 Yazıcı Yönetimi Sistemin Geri Kalanına Nasıl Bağlanır
→ Yazdırma Kuyruğu (6.2)
Hammadde Girişi bir yazdırma işi kuyruğa aldığında, bir printer_id (1–4) belirtir. Yazdırma kuyruğu rotaları bu ID’yi yazıcılar tablosuna karşı doğrular. Arka plan işçileri uygulama başlangıcında yazıcılar tablosundan başlatılır.
→ Hammadde Girişi
Bir malzeme girildikten sonra başarı modalı “Etiket Yazdır” butonu sunar. Bu POST /api/print-queue/queue/{material_id}?printer_id=X çağırır ve işi seçilen yazıcının kuyruğuna gönderir.
→ Hammaddeler Listesi
Hammaddeler Listesi’ndeki yeniden yazdırma eylemi de ID ile belirli bir yazıcıyı hedefler. GET /api/materials/print/preview/{id} endpoint’i, yazıcılar tablosundan yazıcı konfigürasyonunu yükleyen get_default_print_service() kullanır (“Lab” yazıcısını tercih eder, ilk aktif yazıcıya geri döner).
→ Uygulama Başlangıcı (main.py)
initialize_workers(db_url) DB’den tüm aktif yazıcıları okur, her yazıcı için bir PrintWorker daemon thread’i oluşturur, her birini CUPS’a otomatik kaydeder ve yoklamayı başlatır. İşçiler dijital kuyruk ile fiziksel donanım arasındaki köprüdür.
Mimari içgörü: Yazıcı Yönetimi bir donanım soyutlama katmanıdır. Sistemin geri kalanı asla doğrudan yazıcılarla konuşmaz — bir printer_id ile iş kuyruğa alır ve işçi thread’leri CUPS/IPP üzerinden fiziksel iletişimi yönetir. Bu ayrıştırma, bir yazıcının Hammadde Girişi veya Hammaddeler Listesi’nde hiçbir kod değişikliği olmadan değiştirilebileceği, IP’sinin güncellenebileceği veya çevrimdışı alınabileceği anlamına gelir. assigned_materials alanı kullanıcı arayüzü için meta veridir (kullanıcıların doğru yazıcıyı seçmesine yardımcı olur) ancak kuyruk düzeyinde uygulanmaz — herhangi bir yazıcı teknik olarak herhangi bir malzemenin etiketini yazdırabilir.
6.2 Yazdırma İzleme (Print Job Monitor)
6.2.1 Amaç ve İş Bağlamı
Her malzeme etiket yazdırması bir iş kuyruğundan geçer. İş, kullanıcı Hammadde Girişi veya Hammaddeler Listesi’nde “Yazdır”a tıkladığı anda oluşturulur ve bir arka plan işçisi bir saniye içinde onu alır. Yazdırma İzleme, bu görünmez boru hattını görünür kılan gerçek zamanlı panodur: kaç iş bekliyor, hangileri şu anda yazdırılıyor, hangileri başarılı oldu, hangileri başarısız oldu ve neden.
İki amaca hizmet eder: izleme (yazıcılar yetişebiliyor mu? başarısızlık var mı?) ve müdahale (başarısız bir işi yeniden dene, kuyruktakini iptal et). Bu alt modül olmadan, başarısız bir yazdırma 3 denemeden sonra sessizce kaybolur ve kimse bir malzemenin etiketinin eksik olduğunu bilmez.
6.2.2 Veritabanı Şeması
Tek tablo: print_jobs (model dosyası: 69 satır)
| Sütun | Tip | Kısıtlamalar | Amaç |
|---|---|---|---|
id | Integer PK | Otomatik artış, indeksli | Benzersiz iş tanımlayıcı |
material_id | Integer FK → raw_materials | NOT NULL | Bu etiketin hangi malzeme için olduğu |
qr_code | String(50) | NOT NULL | QR kod metni. Reddedilen malzemeler için “ - REDDEDILDI” eki içerir |
printer_id | Integer | NOT NULL, indeksli | Hedef yazıcı (1–4) |
copies | Integer | NOT NULL, varsayılan 1 | Yazdırılacak etiket kopya sayısı |
status | String(20) | NOT NULL, indeksli, varsayılan “queued” | İş yaşam döngüsü durumu |
retry_count | Integer | NOT NULL, varsayılan 0 | İşçinin kaç kez yeniden denediği (maks 3) |
error_message | Text | NULLABLE | İş başarısız olursa hata detayları |
requested_by | Integer FK → users | NOT NULL | Yazdırmayı tetikleyen kullanıcı |
requested_at | DateTime | NOT NULL, otomatik | İşin kuyruğa alındığı zaman |
started_at | DateTime | NULLABLE | İşçinin yazdırmaya başladığı zaman |
completed_at | DateTime | NULLABLE | İşin tamamlandığı veya başarısız olduğu zaman |
material_type | String(50) | NULLABLE, denormalize | Join olmadan hızlı gösterim için malzeme türü |
lot_number | String(100) | NULLABLE, denormalize | Hızlı gösterim için lot numarası |
supplier_name | String(200) | NULLABLE, denormalize | Hızlı gösterim için tedarikçi adı |
PrintJobStatus Enum (5 durum)
class PrintJobStatus(str, Enum): QUEUED = "queued" # Kuyrukta bekliyor PRINTING = "printing" # İşçi şu anda yazdırıyor COMPLETED = "completed" # Etiket başarıyla yazdırıldı FAILED = "failed" # 3 denemeden sonra başarısız CANCELLED = "cancelled" # Admin tarafından manuel iptal
İş Yaşam Döngüsü
Denormalizasyon Stratejisi
Üç sütun (material_type, lot_number, supplier_name) bilinçli olarak raw_materials ve suppliers’dan denormalize edilmiştir. Bu, izleme panosunun tablolar arası pahalı join’ler olmadan tüm iş verilerini göstermesini sağlar — 500’e kadar iş listeleyen bir sayfa için kritiktir.
6.2.3 API Sözleşmesi — 5 Endpoint
| Metot | Yol | Yetki | Ne Yapar |
|---|---|---|---|
POST | /api/print-queue/queue/{material_id}?printer_id=X | super_admin, lab_user, operator | Yazdırma işi kuyruğa al. QUEUED durumuyla PrintJob oluşturur. Kopya sayısı material.quantity’den (varsayılan 1). Malzeme reddedilmişse QR’ye “ - REDDEDILDI” ekler. material_type, lot_number, supplier_name denormalize eder. |
GET | /api/print-queue/jobs | Yalnızca super_admin | İşleri filtrelerle listele: ?status=, ?printer_id=, ?limit= (varsayılan 100, maks 500). requested_at DESC sıralı. Tamamlanmışsa duration saniye hesaplar. |
POST | /api/print-queue/jobs/{id}/retry | super_admin veya lab_user | Başarısız işi sıfırla: durum → QUEUED, retry_count → 0, error_message temizle, zaman damgalarını sıfırla. İşçi yeniden alır. |
DELETE | /api/print-queue/jobs/{id} | Yalnızca super_admin | Kuyruktaki işi iptal et. Durum PRINTING ise engellenir (“Devam eden iş iptal edilemez”). Durum → CANCELLED, completed_at damgalanır. |
GET | /api/print-queue/stats | Yalnızca super_admin | İş sayılarını döndürür: { queued, printing, completed, failed, total }. |
6.2.4 CRUD Akışı
Oluştur (Yazdırma İşi Kuyruğa Al):
- Hammaddeler Listesi’nde bir malzeme satırındaki yazdır ikonuna tıkla (palet/makara için devre dışı)
- Yazıcı seçim modalı açılır: QR kodu, etiket sayısı (
material.quantityveya 1) veGET /api/printers/list?active_only=true’den çekilen aktif yazıcıların açılır listesini gösterir - Yazıcı seç → “Yazdır”a tıkla
POST /api/print-queue/queue/{material_id}?printer_id=X- Backend malzemenin var olduğunu doğrular, ilişkiden tedarikçi adını alır, malzemenin reddedilip reddedilmediğini kontrol eder (QR’ye “ - REDDEDILDI” ekler), tür/lot/tedarikçiyi iş satırına denormalize eder
- Başarıda: toast “Yazdırma işi kuyruğa eklendi (#123)” → modal kapanır
- Arka plan işçisi işi 1 saniye içinde alır ve yazdırmaya başlar
Oku (İşleri İzle):
- /admin/print-monitor sayfasına git
- Sayfa yüklenir →
GET /api/print-queue/jobs?limit=200+GET /api/print-queue/stats - Üstte 4 istatistik kartı render edilir: Bekleyen (gri), Yazdırılıyor (mavi), Tamamlanan (yeşil), Başarısız (kırmızı)
- ProTable (16 sütun) tüm işleri render eder: ID, QR kod (mavi etiket), malzeme türü (renk kodlu Türkçe etiket), lot, tedarikçi, yazıcı (filtrelenebilir 1–4), adet (kalın), durum (renk kodlu etiket), deneme sayısı (X/3 uyarı etiketi > 0 ise), hata mesajı (kırmızı tooltip), kullanıcı, istek/başlangıç/bitiş zaman damgaları (Türkiye saat dilimi), süre (saniye), işlemler
- İstemci tarafı arama QR kod, lot, tedarikçi, kullanıcı, durum, malzeme türü, ID ve yazıcı üzerinde — Türkçe çeviriler dahil — filtreler
Yeniden Dene (Başarısız → Kuyrukta):
- Yeniden dene butonu (RedoOutlined) yalnızca “başarısız” durumlu satırlarda görünür
- Yeniden dene’ye tıkla →
POST /api/print-queue/jobs/{id}/retry - Backend sıfırlar: durum → QUEUED, retry_count → 0, error_message temizlenir, started_at ve completed_at null yapılır
- Başarıda: toast “İş #{id} tekrar kuyruğa eklendi” → tablo + istatistikler yenilenir
- İşçi sonraki yoklama döngüsünde (1 saniye içinde) işi yeniden alır
İptal (Kuyrukta → İptal Edildi):
- İptal butonu (CloseCircleOutlined, tehlike) yalnızca “kuyrukta” durumlu satırlarda görünür
- İptal’e tıkla → onay modalı: “İş #{id} iptal edilsin mi?” ile “İptal Et” (tehlike) / “Vazgeç”
- Onayda:
DELETE /api/print-queue/jobs/{id} - Backend işin PRINTING olmadığını doğrular (“Devam eden iş iptal edilemez” ile engeller), durum → CANCELLED, completed_at damgalanır
- Başarıda: toast “İş #{id} iptal edildi” → tablo + istatistikler yenilenir
6.2.5 Arka Plan İşçisi — İşler Nasıl Gerçekten Yazdırılır
Bu izleme sayfası ile fiziksel yazdırma arasındaki bağlantı PrintWorker’dır (292 satır, 6.1.6’da açıklanmıştır). İşçi bir işi işlerken tam veri akışı:
material_data Dict (İşçi Tarafından Oluşturulur)
| Anahtar | Kaynak |
|---|---|
qr_code | job.qr_code (reddedilmişse “REDDEDILDI” içerir) |
material_type | job.material_type (denormalize) |
lot_number | job.lot_number veya material.lot_number |
supplier_name | job.supplier_name (denormalize) |
weight | material.weight (DB’den canlı) |
received_date | material.received_date (DB’den canlı) |
entered_by | user.full_name veya user.username (canlı arama) |
notes | material.notes (DB’den canlı) |
Hibrit yaklaşıma dikkat edin: bazı alanlar denormalize iş satırından gelir (hızlı, join yok), ağırlık, tarih, kullanıcı adı ve notlar ise DB’den canlı çekilir (her zaman güncel).
Yeniden Deneme Mantığı (Otomatik)
| retry_count | Yazdırma Başarısız | Sonuç |
|---|---|---|
| 0 | İlk deneme başarısız | retry_count → 1, durum → QUEUED, hata saklanır |
| 1 | İkinci deneme başarısız | retry_count → 2, durum → QUEUED |
| 2 | Üçüncü deneme başarısız | retry_count → 3, durum → QUEUED |
| 3 | Dördüncü deneme başarısız | durum → FAILED, completed_at damgalanır |
Otomatik 3 deneme tükendikten sonra, iş panoda “Başarısız” olarak “3/3” deneme sayısıyla görünür. Bir admin veya lab kullanıcısı daha sonra manuel olarak yeniden deneyebilir (sayacı 0’a sıfırlar).
6.2.6 Frontend Mimarisi
Tek dosya: src/pages/Admin/PrintJobMonitor/index.tsx (509 satır). Rota: /admin/print-monitor.
Bileşen Yapısı
4 İstatistik Kartı (Row, gutter 16)
Bekleyen İşler (gri #8c8c8c), Yazdırılıyor (mavi #1890ff), Tamamlanan (yeşil #52c41a), Başarısız (kırmızı #ff4d4f). Font boyutu 24px. Her tablo yüklemesinden ve yeniden dene/iptal eylemlerinden sonra yenilenir.
ProTable (16 sütun)
Varsayılan sayfa boyutu 50, maks 500. Kaydırma genişliği 1800px. Sütunlar: ID (sıralanabilir, sabit sol), QR kod (mavi etiket), malzeme türü (renk kodlu), lot, tedarikçi, yazıcı (filtrelenebilir), adet (kalın), durum (filtrelenebilir, renk kodlu), deneme sayısı, hata (kırmızı tooltip), kullanıcı, 3 zaman damgası (Türkiye SD), süre, işlemler (sabit sağ).
Araç Çubuğu
Arama girdisi (Türkçe çeviriler dahil tüm sütunlarda istemci tarafı filtreleme) + tablo seçenekleri (yoğunluk, yenile, sütun ayarları). Başlık: “Yazdırma İşleri”.
İşlem Butonları (koşullu)
Yeniden Dene (RedoOutlined): yalnızca “başarısız” satırlarda görünür. İptal (CloseCircleOutlined, tehlike): yalnızca “kuyrukta” satırlarda görünür. “Yazdırılıyor”, “tamamlandı” veya “iptal edildi” satırlarında işlem yok.
Tarih Biçimlendirme
Tüm zaman damgaları veritabanında UTC olarak saklanır. Frontend bunları dayjs.utc(dateStr).tz('Europe/Istanbul') kullanarak dönüştürür ve D.MM.YYYY HH:mm:ss biçiminde gösterir (örn. “18.02.2026 14:30:45”).
Malzeme Türü Etiketleri (Renk Eşlemesi)
| Tür | Etiket Rengi | Türkçe Etiket |
|---|---|---|
raw_copper | orange | Bakır |
raw_tin | cyan | Kalay |
raw_plastic | purple | Plastik |
raw_catalyst | magenta | Katalizör |
raw_dye | volcano | Boya |
raw_antirodent | geekblue | Antirodent |
WebSocket Yok — Manuel Yenileme
ERP’deki diğer sayfaların aksine, Yazdırma İzleme gerçek zamanlı güncellemeler için WebSocket kullanmaz. Tablo ve istatistikler mutasyonlardan (yeniden dene, iptal) sonra actionRef.current?.reload() ile ve tablonun yerleşik yenile butonuyla yenilenir. Otomatik yoklama yoktur.
6.2.7 Yetki Modeli
Sayfa ID: admin.yazdirma_izleme
| Yetki ID | Etiket | Açıklama |
|---|---|---|
access_page | Sayfaya Erişim | Yazdırma izleme sayfasını görüntüleme |
view_jobs | İşleri Görüntüle | Yazdırma işlerini görme |
view_stats | İstatistikler | İstatistik kartlarını görme |
retry_job | Tekrar Dene | Başarısız işi tekrar çalıştırma |
cancel_job | İşi İptal Et | Bekleyen işi iptal etme |
refresh_data | Yenile | Veriyi yenileme butonu |
Backend uygular: super_admin her şeyi yapabilir. lab_user başarısız işleri yeniden deneyebilir. operator yalnızca yeni iş kuyruğa alabilir (Hammadde Girişi üzerinden) ancak izleme panosuna erişemez.
6.2.8 Yazdırma İzleme Sistemin Geri Kalanına Nasıl Bağlanır
← Hammadde Girişi (Kaynak)
Bir malzeme girildikten sonra başarı modalının “Yazdır” butonu POST /print-queue/queue/{id} ile bir yazdırma işi kuyruğa alır. Bu birincil iş oluşturma yoludur.
← Hammaddeler Listesi (Kaynak)
Herhangi bir malzeme satırındaki yeniden yazdır butonu bir yazıcı seçim modalı açar (QR kodu + etiket sayısı gösterir), sonra aynı endpoint üzerinden kuyruğa alır. Palet ve makaralar için devre dışı.
→ Yazıcı Yönetimi (6.1)
Yazdırma işçileri yazıcılar tablosundan başlatılır. Hammaddeler Listesi’ndeki yazıcı seçim modalı /api/printers/list’den aktif yazıcıları çeker. İşteki yazıcı ID’si 6.1’de yapılandırılmış fiziksel bir cihaza karşılık gelir.
→ PrintWorker (Arka Plan)
Yazıcı başına bir daemon thread’i print_jobs tablosunu her 1 saniyede yoklar, QUEUED işleri FIFO sırasıyla işler, otomatik yeniden denemeleri yönetir (maks 3) ve iş durumunu günceller. 6.1.6’da detaylı açıklanmıştır.
Mimari içgörü: Yazdırma kuyruğu engellenmeyen, at-ve-unut bir sistemdir. Kullanıcı “Yazdır”a tıkladığında, API hemen bir iş ID’si ile döner — kullanıcı fiziksel yazıcıyı beklemez. İşçi bunu asenkron olarak işler. Bu tasarım, Hammadde Girişi’nin yavaş veya çevrimdışı yazıcılarda asla engellenmemesi anlamına gelir. İzleme panosu bu asenkronluğun bir gözlemlenebilirlik boşluğu yarattığı için vardır: attıktan ve unuttukuntan sonra ne olduğunu görecek bir yere ihtiyacınız var. Malzeme verisinin iş satırına denormalizasyonu bilinçli bir performans ödünüdür — izleme sayfası 500 işle bile hızlı yüklenir çünkü asla raw_materials veya suppliers’a join yapmaz.
6.3 AI Ayarları (AI Settings)
6.3.1 Amaç ve İş Bağlamı
ERP, şu anda API entegrasyonu üzerinden Google Gemini tarafından desteklenen (OpenAI ve Anthropic Claude tamamen entegre ve hazır) bir AI asistan içerir. Asistan, kullanıcılar adına dahili API’leri çağırarak siparişler, malzemeler, üretim ve envanter hakkında soruları yanıtlayabilir. AI Ayarları, bu asistanın yapılandırma ve izleme merkezidir: API anahtar yönetimi, model seçimi, parametre ayarlama, kullanım istatistikleri ve her AI etkileşiminin kapsamlı denetim izi.
Mevcut API tabanlı entegrasyon bir hızlı demo katmanıdır — uzun vadeli vizyon paralel olarak gelişirken anlık AI yetenekleri sağlar. Yol haritası, tüm fabrika genelinde özel, yerel olarak barındırılan modeller inşa etmek ve dağıtmaktır: üretim optimizasyonu, kalite kontrol, öngörücü bakım, anomali tespiti — esasen her şeyi sürekli izleyen ve kontrol eden görünmez AI ajanları. Dil/arama bileşeni için özellikle, ERP’ye özgü arama sorgusu anlaması için ince ayar yapılmış hafif ~1B parametreli bir model (Qwen veya benzeri) kullanılacak ve harici API bağımlılığı tamamen ortadan kaldırılacaktır. Bu ayarlar sayfasındaki çoklu sağlayıcı mimarisi bu geçiş göz önünde bulundurularak tasarlanmıştır — harici API’den yerel model endpoint’ine geçiş bir yeniden yazma değil, konfigürasyon değişikliğidir.
AI ajanının kendisi ana backend’den ayrı bir serviste (solen_ai_service) yaşar. Bu alt modül kontrol düzlemini sağlar — bir yöneticinin koda veya konfigürasyon dosyalarına dokunmadan AI’yı yönetmesini sağlayan düğmeler ve panolar.
6.3.2 Veritabanı Şeması — 47 Sütunlu Denetim Günlüğü
AI sistemi adli düzeyde denetim günlüğü için iki tablo kullanır:
ai_audit_logs (47 sütun)
Her tekil AI etkileşimi tam bağlamla kaydedilir. Sütunlar 8 gruba ayrılmıştır:
| Grup | Sütunlar | Ne Yakalar |
|---|---|---|
| Kimlik (10) | user_id, username, user_type, session_id, session_token, ip_address, user_agent, device_type, browser, os | Kim sordu, nereden, hangi cihazda |
| Sorgu (6) | original_query, query_language, query_length, query_type, query_category, detected_entities | Ne soruldu, sınıflandırıldı ve ayrıştırıldı (örn. {"order_id": 377}) |
| AI İşleme (9) | ai_model, ai_model_version, ai_preprocessing, ai_reasoning, ai_confidence, selected_tool, tool_params, tool_params_sanitized, alternative_tools | AI nasıl karar verdi, hangi aracı seçti, hangi alternatifleri düşündü |
| API Çağrısı (6) | api_endpoint, api_method, api_request_headers, api_response_status, api_response_data, api_response_size_bytes | AI’nın kullanıcı adına yaptığı dahili API çağrısı |
| Sonuç (6) | success, error_type, error_message, error_stack, final_response, response_type | AI ne yanıtladı, başarılı mı oldu, değilse hata detayları |
| Performans (4) | total_duration_ms, ai_processing_ms, api_call_ms, response_generation_ms | Zamanlama dağılımı: AI düşünme + API çağrısı + yanıt üretme |
| Güvenlik (4) | security_flags, rate_limit_status, was_blocked, block_reason | Enjeksiyon tespiti, hız sınırlama, engellenen sorgular |
| Meta (2) | created_at, metadata | Zaman damgası ve genişletilebilir JSON meta verisi |
11 indeks sorguları optimize eder: user_id, username, session_id, ip_address, selected_tool, success, created_at üzerinde tekli; (user_id, created_at), (selected_tool, created_at), (success, created_at), (ip_address, created_at) üzerinde bileşik.
ai_audit_log_summaries (12 sütun)
Günlük toplu istatistikler: toplam/başarılı/başarısız/engellenen sorgular, benzersiz kullanıcılar ve IP’ler, en çok kullanılan araçlar, en çok kategori, ortalama yanıt süreleri, hata dağılımı. Günde bir satır. Şu anda API üzerinden sunulmuyor — gelecekteki analitik panoları için ayrılmış.
6.3.3 API Sözleşmesi — 12 Endpoint
| Metot | Yol | Ne Yapar |
|---|---|---|
POST | /api/ai/chat | AI ajanına sorgu gönder. AI’nın etkin olup olmadığını kontrol eder. Yanıt, kullanılan araçlar, zamanlama döndürür. Hataları kullanıcıdan gizler. |
GET | /api/ai/status | AI hazırlık durumunu kontrol et: API anahtarı yapılandırılmış mı, model adı, ajan durumu (ready/error/not_initialized). |
GET | /api/ai/models | Sağlayıcıya göre gruplanmış mevcut modelleri listele: tier, açıklama, önerilen bayrağı, yakında bayrağı. |
POST | /api/ai/reset | Mevcut ajan singleton’ını yok et. Sonraki istekte en son konfigürasyonla yeniden başlatılır. |
GET | /api/ai/config | Mevcut konfigürasyonu al: enabled, model_name, max_tokens, temperature, anahtar durumu. |
POST | /api/ai/config | Konfigürasyonu güncelle. Kısmi güncellemeler desteklenir. ai_config.json’a kaydeder. |
GET | /api/ai/stats | Denetim tablosundan kullanım istatistikleri: toplam/başarılı/başarısız sorgular, ort. yanıt süresi, bugünkü sayı. |
GET | /api/ai/audit-logs | Sayfalanmış denetim günlüğü kayıtları. Params: ?limit=100&offset=0. |
GET | /api/ai/api-keys/status | 3 sağlayıcı anahtarının durumu: yapılandırılmış bayrağı + maskeli önizleme (ilk 8 + “...” + son 4 karakter). |
POST | /api/ai/api-keys/save | Sağlayıcı için API anahtarı kaydet. Uzunluk (≥ 20) doğrular, önek kontrol eder (yalnızca uyarı). .env’ye yazar, çalışma zamanı ortamını günceller, ajanı sıfırlar. |
DELETE | /api/ai/api-keys/{provider} | .env ve çalışma zamanı ortamından API anahtarını kaldır. |
POST | /api/ai/api-keys/test/{provider} | Anahtar geçerliliğini test et: Gemini istemci örnekleme, OpenAI/Anthropic modeller endpoint’i ile. |
6.3.4 CRUD Akışı
Oluştur / Güncelle (API Anahtarı):
- “API Anahtarları” sekmesine git → 3 sağlayıcı kartı (Google Gemini, OpenAI, Anthropic Claude) her biri logo, durum etiketi ve şifre girdisi ile
- Şifre alanına API anahtarını gir → “Kaydet”e tıkla
POST /api/ai/api-keys/saveile{ provider, api_key }- Backend doğrular: boş değil, ≥ 20 karakter, önek kontrol (Gemini için AIza, OpenAI için sk-, Anthropic için sk-ant- — yalnızca uyarı, engelleme yok)
solen_ai_service/.envdosyasına yazar, çalışma zamanıos.environ’ı günceller, AI ajan singleton’ını sıfırlar- Başarıda: toast “API anahtarı kaydedildi” + varsa önek uyarısı → kartta maskeli anahtar gösterilir → durum yenilenir
Oku (Genel Bakış Panosu):
- /admin/ai-settings sayfasına git → “Genel Bakış” sekmesi yüklenir
- 4 istatistik kartı: AI durumu (aktif/pasif), bugünkü sorgular, toplam sorgular, ortalama yanıt süresi
- Başarı oranı kartı: dairesel ilerleme grafiği + başarılı/başarısız sayıları
- Bağlantı test kartı: durum, API anahtar durumu, mevcut modeli gösterir. “Bağlantıyı Test Et” butonu
GET /api/ai/statusçağırır
Model Ayarlarını Güncelle:
- “Model Ayarları” sekmesine git
- 4 alanlı form: AI etkin (switch), model (cascader: Sağlayıcı → Model, tier etiketleri ve önerilen yıldızlarıyla), maks token (seçim: 1024/2048/4096/8192), sıcaklık (seçim: 0.1/0.3/0.5/0.7/0.9)
- “Ayarları Kaydet”e tıkla
POST /api/ai/config→ai_config.json’a kaydederPOST /api/ai/reset→ mevcut ajanı yok eder, sonraki sorguda yeni konfigürasyonla yeniden başlatılır- Toast: “Ayarlar kaydedildi - AI yeniden başlatıldı”
API Anahtarı Sil:
- Sağlayıcı kartında “Sil” butonuna tıkla
- Onay modalı
DELETE /api/ai/api-keys/{provider}- Backend anahtarı
.envdosyasından veos.environ’dan kaldırır - Toast: “API anahtarı silindi” → kart yapılandırılmamış duruma döner
API Anahtarı Test Et:
- Yapılandırılmış sağlayıcı kartında “Test Et” butonuna tıkla
POST /api/ai/api-keys/test/{provider}- Backend test eder: Gemini istemci örnekleme ile, OpenAI
GET https://api.openai.com/v1/modelsile, AnthropicGET https://api.anthropic.com/v1/modelsile - Başarı toast’u veya detaylı hata toast’u
6.3.5 AI Sağlayıcı Yapılandırması
| Sağlayıcı | Ortam Değişkeni | Anahtar Öneki | Modeller | Durum |
|---|---|---|---|---|
| Google Gemini | GEMINI_API_KEY | AIza | gemini-3-flash (önerilen), gemini-3-pro, gemini-2.5-flash, gemini-2.5-pro | Aktif |
| OpenAI | OPENAI_API_KEY | sk- | gpt-5.2 (önerilen), gpt-5-mini, o3, gpt-4.1 | Aktif |
| Anthropic Claude | ANTHROPIC_API_KEY | sk-ant- | claude-sonnet-4-5 (önerilen), claude-opus-4-5, claude-haiku-4-5 | Aktif |
Anahtar Saklama Mimarisi
API anahtarları solen_ai_service dizinindeki .env dosyasında saklanır (ana backend’den ayrı). Veritabanında asla saklanmazlar. Kaydetme sırasında anahtar, yeniden başlatma olmadan anlık kullanım için os.environ’da da ayarlanır. Anahtarlar API yanıtlarında asla döndürülmez — yalnızca maskeli önizlemeler (ilk 8 + “...” + son 4 karakter).
Konfigürasyon Saklama
Model ayarları (enabled, model_name, max_tokens, temperature) .env dosyasının yanındaki ai_config.json’da saklanır. Varsayılanlar: enabled=true, model=gemini-3-flash, max_tokens=4096, temperature=0.7.
6.3.6 AI Ajanı — Singleton Mimarisi
AI ajanı (SolenAIAgent) istekler arasında kalıcı bir singleton’dır. İlk AI sorgusunda başlatılır ve açıkça sıfırlanıncaya kadar yeniden kullanılır.
Ajan şu durumlarda sıfırlanır (yok edilir ve yeniden oluşturulur): API anahtarları kaydedildiğinde/silindiğinde, konfigürasyon ayarlar sayfası üzerinden güncellendiğinde veya POST /api/ai/reset çağrıldığında. Bu, ajanın her zaman en son konfigürasyonu kullanmasını sağlar.
Sohbet İstek Akışı
- Kullanıcı
POST /api/ai/chatile{ query, conversation_history, user_type }gönderir - Backend
ai_config.json’ı kontrol eder —enabled: falseise “AI servisi şu an devre dışı” döndürür - Ajan singleton’ını alır veya oluşturur, JWT’den kullanıcı bilgisini çıkarır
agent.process_query(query, history, user_type, ip, username, user_id)çağırır- Ajan dahili olarak: sorguyu ön işler, araç seçer, dahili API çağırır, yanıt üretir, denetim günlüğü yazar
- Backend yanıtı temizler (ham API hatalarını gizler),
{ success, response, tool_used, timing_ms }döndürür
6.3.7 Denetim Günlüğü — Adli Düzeyde İzleme
Her AI etkileşimi ai_audit_logs’a 47 sütun bağlamla bir satır yazar. Denetim günlüğü her sorgu hakkında 7 soruyu yanıtlar:
- Kim? — user_id, username, user_type, oturum bilgisi, IP, cihaz, tarayıcı, işletim sistemi
- Ne? — orijinal sorgu, dil, tür (arama/soru/komut), kategori (sipariş/malzeme/üretim), tespit edilen varlıklar
- Nasıl? — AI model, akıl yürütme, güven skoru, seçilen araç, araç parametreleri, değerlendirilen alternatif araçlar
- Nereye? — çağrılan API endpoint’i, metot, yanıt durumu, yanıt verisi, yanıt boyutu
- Sonuç? — başarı/başarısızlık, hata türü ve mesajı, son yanıt metni, yanıt türü
- Performans? — toplam ms, AI işleme ms, API çağrısı ms, yanıt üretme ms
- Güvenlik? — enjeksiyon bayrakları, hız sınırı durumu, engelleme bayrağı ve nedeni
6.3.8 Frontend Mimarisi
Tek dosya: src/pages/Admin/AISettings/index.tsx (1.177 satır). Rota: /admin/ai-settings.
4 Sekmeli Düzen
Sekme 1: Genel Bakış
4 istatistik kartı (AI durumu, bugünkü sorgular, toplam sorgular, ort. yanıt süresi). Başarı oranı dairesel ilerleme grafiği. Bağlantı test kartı: durum göstergesi, API anahtar bayrağı ve model adı.
Sekme 2: API Anahtarları
3 sağlayıcı kartı (Gemini, OpenAI, Claude) her biri: sağlayıcı logosu, “Aktif” durum etiketi, maskeli anahtar görüntüleme, şifre girdisi, kaydet/test/sil butonları ve sağlayıcının API konsoluna bağlantı ile. Artı AI servis hesabı durum kartı.
Sekme 3: Model Ayarları
Form: etkin switch, model cascader (Sağlayıcı → Model, ikonlar, tier etiketleri, önerilen yıldızlar, API anahtar yoksa devre dışı), maks token seçimi (1024–8192), sıcaklık seçimi (0.1–0.9). Kaydet konfig güncelleme + ajan sıfırlama tetikler.
Sekme 4: Kullanım Geçmişi
Genişletilebilir satırlı ProTable. Sütunlar: zaman damgası, kullanıcı adı + user_type etiketi, kullanılan araç (mavi etiket), durum (başarı/hata), yanıt süresi (renk kodlu: yeşil < 500ms, turuncu 500–1000ms, kırmızı > 1000ms), IP. Genişletilmiş satır: sorgu, AI yanıtı, hata mesajı. Arama, sayfalama (10/20/50), yoğunluk kontrolleri.
6.3.9 Yetki Modeli
AI Ayarları manifest’te granüler buton düzeyinde yetkilere sahip değildir. Erişim modül düzeyinde canAdmin ile kontrol edilir — admin modülüne erişimi olan herhangi bir kullanıcı AI Ayarları’nı görüntüleyebilir. Backend endpoint’lerinde JWT kimlik doğrulaması ötesinde açık yetki kontrolü yoktur.
Bu bilinçli bir tasarım seçimidir: AI konfigürasyonu buton başına bir yetki değil, admin genelinde bir yetenek olarak kabul edilir. Pratikte yalnızca super admin’ler admin modülüne erişir.
6.3.10 AI Ayarları Sistemin Geri Kalanına Nasıl Bağlanır
→ AI Ajanı (Harici Servis)
Ayarlar sayfası SolenAIAgent’ı içeren harici solen_ai_service’i yapılandırır. API anahtarları, model seçimi ve parametreler ajanın okuduğu dosyalarda saklanır. Ajan, backend’e singleton olarak import edilir.
→ AI Arama (Sorgu Ön İşleme)
ai_search_service.py (256 satır) arama sorgularını ön işlemek için Gemini kullanır: Türkçe karakter düzeltme, sorgu sınıflandırma, varlık tespiti. AI kullanılamazsa kural tabanlı işlemeye geri döner.
→ Tüm ERP Modülleri (AI Sohbet Yoluyla)
AI ajanı kullanıcılar adına dahili API’leri çağırabilir — siparişleri, malzemeleri, tedarikçileri, üretim verilerini sorgular. Her modülden veri tüketen ancak asla yazmayan salt okunur bir asistan.
→ Denetim ve Uyumluluk
47 sütunlu denetim günlüğü her AI etkileşiminin eksiksiz adli izini oluşturur: kim ne sordu, AI nasıl işledi, hangi API’yi çağırdı, ne yanıtladı ve ne kadar sürdü. Bu hem hata ayıklamayı hem de güvenlik denetimini destekler.
Mimari içgörü: AI sistemi kontrol düzlemi / veri düzlemi ayrımını izler. Kontrol düzlemi (bu ayarlar sayfası) konfigürasyon, anahtarlar ve izlemeyi yönetir. Veri düzlemi (harici SolenAIAgent) gerçek sorgu işlemeyi yönetir. Bu ayrım, AI ajanının ERP backend’inden bağımsız olarak yükseltilmesi, değiştirilmesi veya ölçeklenmesi anlamına gelir. 47 sütunlu denetim günlüğü bilinçli olarak aşırı mühendislenmiştir — temel günlükleme için gerekenden çok daha fazla bağlam yakalar, çünkü AI adli bilişimi yalnızca AI’nın ne yaptığını değil, o eylemi neden seçtiğini ve hangi alternatifleri değerlendirdiğini anlamayı gerektirir. Çoklu sağlayıcı mimarisi (3 sağlayıcının tamamı — Gemini, OpenAI ve Claude — 30’dan fazla modelle tamamen entegre) AI sağlayıcısını değiştirmenin bir kod değişikliği değil konfigürasyon değişikliği olduğu anlamına gelir.
6.4 Kullanıcı Yönetimi (User Management)
6.4.1 Amaç ve İş Bağlamı
Kullanıcı Yönetimi, tüm ERP’nin kimlik ve yetkilendirme omurgasıdır. Diğer tüm modüller — Hammadde, Teknik, Sipariş, Üretim, Stok, Lab, Admin — iki soruyu yanıtlamak için bu alt modüle bağımlıdır: “Bu kişi kim?” (kimlik doğrulama) ve “Ne yapmaya yetkili?” (yetkilendirme). Sistemdeki en karmaşık alt modüldür çünkü hibrit bir yetki modeli uygular: eski rol tabanlı erişimin üzerine katmanlanan, 8 modül, 26+ sayfa ve 200+ eylem üzerinde tek tek UI butonlarına kadar görünürlüğü kontrol eden granüler sayfa+buton yetki sistemi.
Fabrikada üç temel kullanıcı arketipi vardır: Süper Admin (tam sistem kontrolü, masaüstü), Lab Kullanıcısı (kalite testi, masaüstü) ve Operatör (makine kullanımı, mobil kiosk). Bunların ötesinde sistem, her biri elle hazırlanmış yetkilerle sınırsız özel kullanıcı tipini destekler.
6.4.2 Veritabanı Şeması — 6 Tablo, Joined-Table Kalıtım
users (17 sütun) — Temel Kimlik Tablosu
| Sütun | Tip | Detay |
|---|---|---|
id | Integer PK | Otomatik artan, indeksli |
email | String(320) | Benzersiz, indeksli, boş olamaz |
hashed_password | String(1024) | bcrypt hash, boş olamaz |
is_active | Boolean | Varsayılan True |
is_superuser | Boolean | Varsayılan False (FastAPI-Users mirası) |
is_verified | Boolean | Varsayılan False |
username | String(50) | Benzersiz, indeksli, boş olamaz |
user_type | String(50) | super_admin, lab_user, operator veya özel |
full_name | String(100) | Görünen ad |
status | String(20) | active / inactive / suspended |
last_login | DateTime | Her girişte güncellenir |
created_at | DateTime | UTC zaman damgası |
updated_at | DateTime | Değişiklikte otomatik güncellenir |
preferred_interface | String(20) | mobile / desktop / auto |
device_info | JSON | Son bilinen cihaz detayları |
permissions | Text | JSON string — granüler yetki nesnesi (sayfalar + butonlar) |
force_password_change | Boolean | Varsayılan False, şifre sıfırlamada True olur |
Joined-Table Kalıtım — Uzantı Tabloları
Her kullanıcı tipinin user_id FK → users.id (benzersiz, bire-bir) ile bağlanan özel bir uzantı tablosu vardır. Bunlar tipe özgü meta verileri saklar:
| Tablo | Ek Sütunlar | Amaç |
|---|---|---|
super_admins | admin_level (system/module/user), permissions (JSON liste), access_logs (JSON liste) | Admin hiyerarşisi, eylem denetim izi |
lab_users | lab_department, certifications (JSON liste), test_specializations (JSON liste), shift_schedule (JSON dict) | Lab’a özgü yeterlilikler ve vardiyalar |
operators | assigned_machines (JSON liste), shift_schedule (JSON dict), skill_level (junior/senior/expert), certifications (JSON liste) | Makine atamaları ve beceri takibi |
SQLAlchemy backref’ler navigasyon sağlar: user.super_admin_profile, user.lab_user_profile, user.operator_profile.
user_sessions (11 sütun)
| Sütun | Tip | Detay |
|---|---|---|
id | Integer PK | Otomatik artan |
user_id | Integer FK | users.id’ye referans |
session_token | String(255) | Benzersiz, indeksli — JWT erişim token’ı |
refresh_token | String(255) | Benzersiz, indeksli |
login_time | DateTime | Oturum ne zaman başladı |
logout_time | DateTime | Çıkışa kadar null |
expires_at | DateTime | Token süre dolma zamanı |
ip_address | String(45) | IPv6 hazır |
user_agent | Text | Tarayıcı/cihaz string’i |
device_type | String(20) | mobile / desktop / tablet |
status | String(20) | active / expired / terminated |
user_roles (7 sütun)
Yeniden kullanılabilir yetki şablonları (rol tanımları). Her rol, kullanıcılara hızla uygulanabilen tam bir yetki JSON’ı saklar.
| Sütun | Tip | Detay |
|---|---|---|
id | Integer PK | Otomatik artan |
name | String(50) | Benzersiz, örn. “Lab Teknisyeni” |
description | Text | Okunabilir rol açıklaması |
permissions | Text | JSON string — tam yetki yapısı |
is_system | Boolean | Sistem rolleri silinemez |
created_at | DateTime | UTC |
updated_at | DateTime | Otomatik güncellenir |
user_activity_logs (11 sütun)
Kullanıcılar üzerindeki her yönetim eylemi için denetim izi. username hızlı okuma için denormalize edilmiştir.
| Sütun | Tip | Detay |
|---|---|---|
user_id | Integer FK | Eylemi kim gerçekleştirdi |
username | String(50) | Denormalize |
action | String(50) | create_user, update_user, suspend_user, delete_user, reset_password |
module | String(50) | Her zaman user_management |
target_type | String(50) | Her zaman user |
target_id | Integer | Etkilenen kullanıcının ID’si |
details | Text | Ek bağlam için JSON string |
ip_address | String(50) | İstemci IP |
user_agent | Text | Tarayıcı string’i |
created_at | DateTime | Eylem ne zaman gerçekleşti |
6.4.3 Kimlik Doğrulama Sistemi — JWT Token’lar ve Oturumlar
Token Mimarisi
| Token Tipi | Süre | Payload | Amaç |
|---|---|---|---|
| Erişim Token’ı | 12 saat (varsayılan) | sub (user_id), username, user_type, permissions, type: "access" | Her API isteğini Authorization: Bearer başlığı ile doğrula |
| Yenileme Token’ı | 7 gün | sub (user_id), type: "refresh", jti (benzersiz token ID) | Yeniden giriş yapmadan yeni erişim token’ı üret |
| Operatör Kiosk Token’ı | 6 ay | Erişim token’ı ile aynı | Fabrika kiosk telefonları — sık yeniden girişten kaçın |
6 aylık token sabit kodlanmış bir kontrolle tetiklenir: if user.username == 'operator'. Bu bilinçlidir — paylaşılan operator hesabı, aylarca oturum açık kalması gereken duvara monte telefonlarda kullanılır.
Şifre Sistemi
| İşlem | Uygulama |
|---|---|
| Hashleme | passlib ile bcrypt şeması. CryptContext(schemes=["bcrypt"], deprecated="auto") |
| Doğrulama | pwd_context.verify(plain, hashed) — sabit zamanlı karşılaştırma |
| Otomatik Üretim | secrets.choice() ile ascii_letters + digits + "!@#$%", 12 karakter |
| Doğrulama (Oluşturma) | Min 8 karakter, büyük harf + küçük harf + rakam içermeli |
| Doğrulama (Giriş) | Min 5 karakter (operatör şifreleri için örn. op123) |
Uçtan Uca Giriş Akışı
- Kullanıcı
POST /auth/login’a kullanıcı adı + şifre gönderir - Backend kullanıcıyı kullanıcı adı veya e-posta ile sorgular (büyük/küçük harf duyarsız)
is_active == Truevestatus != "suspended"kontrol eder- Şifreyi bcrypt ile doğrular
last_loginzaman damgasını güncelleruser_id,username,user_type,permissionsile JWT payload oluşturur- Operatör hesabıysa: 6 ay süre; değilse 12 saat
UserSessionsatırı oluşturur (session_token, refresh_token, cihaz bilgisi, IP, süre){ access_token, refresh_token, expires_in, user }döndürür- Frontend token’ları ve kullanıcıyı
localStorage’a kaydeder (anahtarlar:solen_auth_token,solen_refresh_token,solen_current_user) - Operatörler
/production’a, diğerleri/welcome’a yönlendirilir
Kiosk Otomatik Giriş
Giriş sayfası fabrika kiosk cihazlarını iki şekilde algılar:
- User-Agent algılama: tarayıcı user-agent string’inde “FullyKiosk” kontrolü (Fully Kiosk Browser fabrika telefonlarında çalışan uygulamadır)
- Gizli URL token’ı: URL’de
?kiosk=SOLEN_FACTORY_2024_KIOSK_SECRETkontrolü
Eşleşme olursa sayfa otomatik olarak operator / op123 ile giriş yapar ve /production’a yönlendirir — insan etkileşimi gerekmez.
Token Yenileme ve Çıkış
- Yenileme:
POST /auth/refreshile yenileme token’ı → doğrular, yeni erişim token’ı üretir, yeni oturum oluşturmaz - Çıkış:
POST /auth/logoutile erişim token’ı → oturumstatus = "terminated"velogout_timeayarlanır → frontendlocalStorage’ı temizler
6.4.4 Yetki Sistemi — En Karmaşık Bölüm
Yetkilendirme sistemi, rota düzeyinden tek tek buton görünürlüğüne kadar erişimi kontrol eden 5 katmanlı bir mimaridir:
Katman 1: Yetki Manifesti (permissionManifest.ts, 565 satır)
Tüm ERP’deki her yetkilendirilebilir eylemin statik, merkezi tanımı. Modül → Sayfa → Buton hiyerarşisi:
| Modül | Sayfalar | Toplam Buton | Öne Çıkanlar |
|---|---|---|---|
| Dashboard | 1 (Ana) | 3 | access_page, view_stats, view_charts |
| Hammadde | 3 (Giriş, Liste, Tedarikçi) | 30 | Giriş formları için 12, liste için 11 (hard_delete dahil), tedarikçiler için 7 |
| Lab | 2 (Panel, Test) | 5 | Lab erişimi, test yönetimi |
| Teknik | 6 (Panel, Kablo Tasarım, Makine, Standart, Kablo DB, Markalama) | 32 | Tek başına Kablo Playground için 11 |
| Sipariş | 3 (Siparişlerim, Oluştur, Müşteri) | 17 | Sipariş CRUD, müşteri yönetimi |
| Üretim | 12 (Planlama, 6 makine, Aktarma, Paletleme, Sevkiyat, Liste, Geçmiş) | ~40 | Makine tipi başına üretim başlat/durdur, planlama, sevkiyat |
| Stok | 3 (Ürün, Hammadde, Projeksiyon) | 14 | Görüntüle, dışa aktar, filtrele, stok ayarla |
| Admin | 3 (Yazdırma İzleme, Yazıcı, Kullanıcı) | 22 | Kullanıcı Yönetimi için 9 (manage_permissions dahil) |
Toplam: 8 modül, 26+ sayfa, 200+ buton.
Her butonun meta verisi vardır:
interface ButtonPermission { id: string; // örn. "hard_delete_material" label: string; // örn. "Kalıcı Silme" description: string; // örn. "Malzemeyi veritabanından tamamen siler" critical?: boolean; // true = yetki düzenleyicide kırmızı vurgulanmış }
Manifest ayrıca yardımcı fonksiyonlar da export eder: createEmptyPermissions() (tümü false), createFullPermissions() (tümü true), getAllPages(), getAllButtons().
Katman 2: Buton Kayıt Defteri (buttonRegistry.ts, 130 satır)
Statik manifeste dinamik bir tamamlayıcı. Bileşenler çalışma zamanında registerPageButtons() ile butonlarını kaydedebilir. buildCompleteManifest() fonksiyonu statik manifest sayfalarını dinamik kayıt defteri butonlarıyla birleştirir. Bu, yeni sayfaların merkezi manifest dosyasını değiştirmeden yetkilerini kendilerinin kaydetmesine olanak tanır.
Katman 3: Erişim Kontrolü — Rota Korumaları (access.ts, 93 satır)
Her rota değişikliğinde çalışır. Mevcut kullanıcının permissions JSON’ını ayrıştırır ve routes.ts tarafından tüketilen boolean bayraklar döndürür:
return { canAdmin: canAccessModule('admin'), // /admin/* rotalarını korur canLab: canAccessModule('lab'), // /lab/* rotalarını korur canProduction: canAccessModule('production'), canHammadde: canAccessModule('hammadde'), canTeknik: canAccessModule('teknik'), canSiparis: canAccessModule('siparis'), canStok: canAccessModule('stok'), canDashboard: canAccessModule('dashboard'), // ... artı alt sayfa korumaları };
canAccessModule(prefix), o modül altındaki herhangi bir sayfa access: true ise true döndürür. Rotalar bunları koruma olarak kullanır: rota konfigürasyonunda access: 'canAdmin'.
Katman 4: Yetki Yardımcıları — Bileşen Düzeyi (permissions.ts, 145 satır)
Tek tek bileşenler için ince ayar kontrolleri sağlar:
canAccessModule(module)— modül etkin mi?canPerformAction(module, action)— belirli eylem izinli mi?hasSpecialPermission(permission)— örn.hard_delete
Ayrıca React sarıcı bileşenleri export eder:
<PermissionButton module="hammadde" action="delete">— yetkiye göre butonu göster/gizle<PermissionGuard module="admin" action="manage">— herhangi bir bileşeni yetki kontrolüyle sar, reddedilirse fallback göster
Katman 5: Backend Zorlama (permission_checker.py, 200 satır)
Sunucu tarafı aynası. Bir kullanıcı frontend’i atlasa bile backend yetkileri zorlar:
| Fonksiyon | Ne Kontrol Eder |
|---|---|
check_user_permission(user, page_id, button_id) | Kullanıcının permissions JSON’ını ayrıştırır, pages[page_id].access ve pages[page_id].buttons[button_id] kontrol eder |
has_special_permission(user, permission) | special_permissions[permission] kontrol eder |
is_permitted_user(user, required_types) | Eski rol tabanlı kontrol + granüler geri dönüş |
check_permission_smart(user, types, page, button) | Hibrit: önce eski rol kontrolü, sonra granüler, sonra nazik geri dönüş. Geriye uyumlu. |
require_permission(page_id, button_id) | Yetki reddedilirse 403 fırlatan bir FastAPI dependency döndürür |
Süper admin atlama: Her yetki fonksiyonu önce user.user_type == "super_admin" kontrol eder ve hemen True döndürür.
Yetki JSON Yapısı
users.permissions sütununda JSON string olarak saklanır. Frontend ve backend arasındaki sözleşme:
{
"pages": {
"hammadde.hammadde_girisi": {
"access": true,
"buttons": {
"add_copper": true,
"add_tin": false,
"submit_form": true,
"print_qr": true
}
},
"production.planning": {
"access": false,
"buttons": {}
}
}
}
6.4.5 API Sözleşmesi — 14 Endpoint (9 Kullanıcı Yönetimi + 5 Auth)
Kimlik Doğrulama Endpoint’leri (5)
| Metot | Yol | Ne Yapar |
|---|---|---|
POST | /auth/login | Kullanıcı adı/şifre ile doğrula. Erişim + yenileme token’ları ve kullanıcı nesnesi döndürür. |
POST | /auth/logout | Oturumu sonlandır. Oturum durumunu “terminated” yapar ve çıkış zamanını kaydeder. |
POST | /auth/refresh | Yenileme token’ını yeni erişim token’ı ile değiştir. Yeni oturum oluşturmaz. |
GET | /auth/me | Token’dan mevcut kullanıcı bilgisini al. Frontend’in sayfa yenilemede durumu geri yüklemesi için. |
GET | /auth/health | Auth servisi sağlık kontrolü: veritabanı bağlantısı, versiyon, çalışma süresi. |
Kullanıcı Yönetimi Endpoint’leri (9)
| Metot | Yol | Yetki | Ne Yapar |
|---|---|---|---|
GET | /user-management/users/list | super_admin | Tüm kullanıcıları listele. ?status_filter ve ?user_type sorgu parametrelerini destekler. Yetki JSON’ını ayrıştırır. |
GET | /user-management/operators | herhangi doğrulanmış | Aktif kullanıcıları listele (diğer modüllerdeki operatör dropdown’ları için). Yalnızca id, username, full_name döndürür. |
POST | /user-management/users/create | super_admin | Kullanıcı oluştur. Kullanıcı adı/e-posta benzersizliğini doğrular. Verilmezse şifre otomatik üretir. Yetki JSON’ını saklar. Aktivite kaydeder. |
PUT | /user-management/users/{id} | super_admin | Kullanıcı alanlarını güncelle (kullanıcı adı, e-posta, ad, tip, durum, yetkiler, şifre). Aktivite kaydeder. |
POST | /user-management/users/{id}/suspend | super_admin | active ve suspended arasında geçiş yap. Aktivite kaydeder. |
DELETE | /user-management/users/{id} | super_admin | Kullanıcıyı kalıcı olarak sil. Kendini silme engellenir (400). Aktivite kaydeder. |
POST | /user-management/users/{id}/reset-password | super_admin | Yeni 12 karakterlik şifre üret. force_password_change = True ayarlar. Şifreyi döndürür (tek seferlik). Aktivite kaydeder. |
GET | /user-management/roles/list | super_admin | Tüm rol şablonlarını ayrıştırılmış yetkilerle listele. |
GET | /user-management/activity-logs | super_admin | Aktivite günlüklerini sorgula. ?user_id, ?module, ?action, ?limit filtrelerini destekler. |
6.4.6 CRUD Akışı
Oluştur (Yeni Kullanıcı):
- “Yeni Kullanıcı” butonuna tıkla → 3 sekmeli modal açılır
- Sekme 1 – Temel Bilgiler: kullanıcı adı (gerekli, alfanümerik + alt çizgi), e-posta (doğrulanmış), tam ad, şifre (isteğe bağlı — boşsa otomatik üretilir), kullanıcı tipi (seç veya satır içi özel tip oluştur), durum, şifre değiştirme zorunlu onay kutusu
- Sekme 2 – Yetkiler: yetki düzenleyici — üstte 4 hızlı şablon (“Tüm Yetkiler”, “Hiçbiri”, “Operatör Varsayılan”, “Lab User Varsayılan”), ardından kaydırılabilir modül listesi. Her modül sayfaları gösterir, her sayfada: erişim switch’i, “Tümü”/“Hiçbiri” hızlı geçişler, tek tek buton onay kutuları. Kritik butonlar kırmızı vurgulanır. Bir butonu etkinleştirmek sayfanın erişimini otomatik etkinleştirir. Sayfa erişimini kapatmak tüm butonlarını kapatır.
- Sekme 3 – Önizleme: salt okunur özet, erişilebilir modüller → sayfalar → etkin butonları renk kodlu etiketlerle gösterir
- “Oluştur”a tıkla →
POST /user-management/users/createile{ username, email, full_name, user_type, status, permissions, force_password_change, return_password: true } - Backend benzersizliği doğrular (kullanıcı adı, e-posta), şifreyi bcrypt ile hashler, kullanıcı + yetki JSON’ını saklar, aktivite kaydeder
- Şifre otomatik üretildiyse: modal üretilen şifreyi “Bu şifreyi not edin, tekrar gösterilmeyecektir” uyarısıyla gösterir
Oku (Kullanıcı Listesi):
/admin/user-management’a git → ProTableGET /user-management/users/listile yüklenir- 7 sütun: ID (sabit sol), Kullanıcı (kullanıcı adı + tam ad), E-posta, Tip (renkli etiket), Durum (renkli etiket), Son Giriş (UTC → Istanbul), İşlemler (sabit sağ)
- İstemci tarafı arama kullanıcı adı, e-posta, tam ad, kullanıcı tipi ve durum üzerinde aynı anda filtreler
- Sayfalama: sayfa başına 10/20/50/100
- ProTable yoğunluk ve sütun ayarları kontrolleri
Güncelle (Kullanıcı Düzenle):
- Kullanıcı satırındaki düzenle ikonuna (EditOutlined) tıkla → aynı 3 sekmeli modal açılır, kullanıcı verileriyle doldurulmuş
- Mevcut yetkiler yüklenir ve ayrıştırılır (string JSON → nesne dönüşümünü yönetir)
- Şifre alanı düzenleme modunda gizlidir (bunun için Şifre Sıfırla kullanın)
- Herhangi bir alan veya yetkiyi değiştir → “Güncelle”ye tıkla
PUT /user-management/users/{id}ile değişen alanlar + tam yetki nesnesi- Backend doğrular, günceller, aktivite kaydeder
Sil (Kalıcı):
- Kullanıcı satırındaki sil ikonuna (DeleteOutlined, tehlike) tıkla
- Onay modalı: “Bu kullanıcıyı silmek istediğinizden emin misiniz?”
DELETE /user-management/users/{id}- Backend kendini silmeyi engeller (400 hatası). Kullanıcı kaydını kalıcı olarak siler. Aktivite kaydeder.
Askiya Al / Etkinleştir:
- Kullanıcı satırındaki durdur ikonuna (StopOutlined) tıkla
POST /user-management/users/{id}/suspendactivevesuspendedarasında durumu değiştirir. Askıya alınmış kullanıcılar giriş yapamaz.
Şifre Sıfırla:
- Kullanıcı satırındaki anahtar ikonuna (KeyOutlined) tıkla
POST /user-management/users/{id}/reset-password- Backend kriptografik olarak güvenli 12 karakterlik şifre üretir, bcrypt ile hashler,
force_password_change = Trueayarlar - Modal yeni şifreyi uyarıyla bir kez gösterir. Admin şifreyi kullanıcıya bant dışından iletmelidir.
6.4.7 Kullanıcı Tipleri ve Farkları
| Süper Admin | Lab Kullanıcısı | Operatör | Özel Tipler | |
|---|---|---|---|---|
| Arayüz | Masaüstü | Masaüstü | Mobil (kiosk) | Yapılandırılabilir |
| Panel Rotası | /welcome | /lab/dashboard | /production | Varsayılan /welcome |
| Token Süresi | 12 saat | 12 saat | 6 ay | 12 saat |
| Yetki Atlama | Evet — tüm kontroller True döner | Hayır | Hayır | Hayır |
| Varsayılan Modüller | Tümü (all_access) | Lab, Hammadde | Üretim | Hiçbiri (manuel) |
| Uzantı Tablosu | super_admins | lab_users | operators | Yok |
| Kullanıcı Yönetebilir | Evet | Hayır | Hayır | Hayır |
| Otomatik Giriş | Hayır | Hayır | Evet (kiosk) | Hayır |
| Menü Erişimi | ["all"] | ["lab", "welcome"] | ["production"] | Yetkilere bağlı |
Özel tipler (örn. teknik_user, bakim_user, data) doğrudan Kullanıcı Yönetimi modalında oluşturulabilir — kullanıcı tipi dropdown’ının altındaki bir girdi alanı yeni tip adı yazmaya olanak tanır. user_type alanı serbest bir String(50)’dir, enum değil, bu esnekliği sağlar.
6.4.8 Frontend Mimarisi
Tek dosya: src/pages/Admin/UserManagement/index.tsx (960 satır). Rota: /admin/user-management.
ProTable (7 sütun)
| # | Sütun | Genişlik | Detay |
|---|---|---|---|
| 1 | ID | 60px, sabit sol | Sayısal |
| 2 | Kullanıcı | 140px | Kullanıcı adı (kalın) + altında tam ad |
| 3 | E-posta | 200px | Taşmada üç nokta |
| 4 | Tip | 110px | Renkli etiket: super_admin (kırmızı), lab_user (mavi), operator (yeşil), teknik_user (mor), bakim_user (turuncu) |
| 5 | Durum | 100px | active (başarı/yeşil), suspended (uyarı/sarı), inactive (varsayılan/gri) |
| 6 | Son Giriş | 140px | dayjs.utc(date).tz('Europe/Istanbul') formatlı |
| 7 | İşlemler | 160px, sabit sağ | 4 eylem butonu (düzenle, şifre sıfırla, askıya al, sil) |
Yetki Düzenleyici (Modal’ın Sekme 2’si)
Tüm ERP’deki en karmaşık UI bileşeni. 8 modülün her biri için:
- Modül başlığı: ikon ile modül adı
- Sayfa kartları: her sayfa Card bileşeni olarak:
- Başlık: sayfa erişimi için
Switch+ sayfa etiketi + “X/Y” etkin buton sayısı gösteren etiket - Hızlı eylemler: “Tümü” (tümünü etkinleştir) / “Hiçbiri” (tümünü kapat) metin butonları
- Buton ızgarası: her buton için
Row/ColdüzenindeCheckboxbileşenleri - Kritik butonlar: kırmızı metin ve farklı stille vurgulanmış
- Başlık: sayfa erişimi için
- Akıllı geçiş: herhangi bir butonu etkinleştirmek sayfanın erişimini otomatik etkinleştirir. Sayfa erişimini kapatmak tüm butonları kaskad olarak kapatır.
Hızlı Şablonlar
| Şablon | Etki |
|---|---|
| “Tüm Yetkiler” | createFullPermissions() — her sayfa ve her buton true |
| “Hiçbiri” | createEmptyPermissions() — her şey false |
| “Operatör Varsayılan” | Üretim modülü etkin (planlama sayfası hariç, o dışlanmış) |
| “Lab User Varsayılan” | Lab ve Hammadde modülleri etkin |
Önizleme Sekmesi (Sekme 3)
Card bileşenleri kullanan salt okunur özet. Yalnızca erişilebilir modülleri/sayfaları gösterir. Her sayfa etkin butonlarını Tag olarak listeler (kritik olanlar kırmızı). Kaydetmeden önce hızlı görsel onay sağlar.
6.4.9 Aktivite Günlüğü — Admin Denetim İzi
Her kullanıcı yönetimi eylemi log_activity() yardımcı fonksiyonu aracılığıyla user_activity_logs’a kaydedilir:
| Eylem | Kaydedilen Alanlar |
|---|---|
create_user | Kim oluşturdu, hedef kullanıcı ID, kullanıcı adı, IP, user agent |
update_user | Kim güncelledi, hedef kullanıcı ID, değişen alanlar detaylarda |
suspend_user | Kim askıya aldı, hedef kullanıcı ID, yeni durum |
delete_user | Kim sildi, hedef kullanıcı ID |
reset_password | Kim sıfırladı, hedef kullanıcı ID (şifre asla kaydedilmez) |
Günlükler GET /user-management/activity-logs ile user_id, module, action ve limit (varsayılan 200) filtreleriyle sorgulanabilir. Yalnızca süper adminler bu endpoint’e erişebilir.
6.4.10 Yetki Modeli
Kullanıcı Yönetimi sistemdeki en yüksek ayrıcalık düzeyini gerektirir:
| Eylem | Gerekli Rol |
|---|---|
| Kullanıcı listesini görüntüle | yalnızca super_admin |
| Kullanıcı oluştur | yalnızca super_admin |
| Kullanıcı düzenle | yalnızca super_admin |
| Yetkileri yönet | yalnızca super_admin |
| Askıya al / etkinleştir | yalnızca super_admin |
| Şifre sıfırla | yalnızca super_admin |
| Kullanıcı sil | yalnızca super_admin (kendini silme engellenir) |
| Aktivite günlüklerini görüntüle | yalnızca super_admin |
| Operatörleri listele (dropdown) | herhangi doğrulanmış kullanıcı |
Yetki manifestinde Kullanıcı Yönetimi’nin 9 kayıtlı butonu vardır: access_page, view_users, create_user, edit_user, manage_permissions, suspend_user, reset_password, delete_user, view_activity_logs.
Backend rol tabanlı erişim zorlar: /user-management/operators hariç her endpoint current_user.user_type != "super_admin" kontrol eder ve başarısız olursa 403 döndürür.
6.4.11 Kullanıcı Yönetimi Sistemin Geri Kalanına Nasıl Bağlanır
→ Tüm Modüller (Kimlik Doğrulama)
Tüm ERP’deki her API endpoint’i Kullanıcı Yönetimi’nin kimlik doğrulamasına bağımlıdır. get_current_user_dependency() FastAPI dependency’si tüm rota dosyalarına import edilir ve kullanılır. Burada üretilen JWT token’ları herhangi korunan kaynağa erişmenin tek yoludur.
→ Tüm Modüller (Yetkilendirme)
Kullanıcı başına saklanan permissions JSON’ı, her kullanıcının 8 modülün tamamında ne gördüğünü ve ne yapabileceğini kontrol eder. Rota korumaları (access.ts), bileşen korumaları (PermissionGuard) ve backend kontrolleri (permission_checker.py) hepsi aynı yetki yapısından okur.
→ Hammadde Girişi (Operatör Dropdown’ı)
GET /user-management/operators endpoint’i, malzeme giriş formlarındaki ve üretim sayfalarındaki operatör/kullanıcı dropdown’larını besler. Herhangi doğrulanmış kullanıcı buna erişebilir, modüller arasında formların “bu malzemeyi kim girdi” göstermesini sağlar.
→ Üretim Sayfaları (Kiosk Otomatik Giriş)
Kiosk otomatik giriş sistemi (?kiosk=... token’ı veya Fully Kiosk algılaması) fabrika katı cihazları için giriş formunu tamamen atlar, paylaşılan operatör hesabının 6 aylık token’ıyla doğrudan /production’a iner.
Mimari içgörü: Kullanıcı Yönetimi tüm ERP’nin çekim merkezidir. Her modül ona bağımlıdır ama o hiçbir modüle bağımlı değildir. 5 katmanlı yetki mimarisi (manifest → kayıt defteri → rota korumaları → bileşen korumaları → backend zorlama) derinlemesine savunma sağlar: bir katman atlanılsa bile diğerleri hala erişim kontrolünü zorlar. Hibrit yetki modeli (eski rol tabanlı + granüler sayfa+buton JSON) pragmatik bir mühendislik kararıdır — sistem basit rol kontrollerinden granüler yetkilere tam bir yeniden yazma gerektirmeden evrildi. check_permission_smart() fonksiyonu bunu somutlaştırır: önce yeni sistemi dener, eskiye geri döner ve nazikçe degrade olur. 200+ buton manifesti, tek tek kayıt düzeyinde erişim kontrolüne gitmeden mümkün olan en ince ayarlı yetki sistemini oluşturur. 6 aylık kiosk token’ı, üretim katındaki paylaşılan cihazların her 12 saatte bir BT müdahalesi olmadan “çalışması” gereken bir fabrika ortamı için alışılmadık ama pratik bir seçimdir.