🗄️ Bölüm 3
Veritabanı Tasarımı — Çekirdek ER Modeli

PostgreSQL üzerinde 22 tablo + 16 enum. SRS V5'teki tüm tablolar korunmuş; eksik kalan iş atama, sefer, bildirim, abonelik ve misafir ilan yapıları tamamlanmıştır. Çalıştırılabilir şema: db/schema.sql

🧭 İlişkisel verinin dışında: canlı araç konumu Redis'te (TTL'li anahtar, sadece SOS anı DB'ye yazılır), evrak/araç fotoğrafları S3'te (URL referansı DB'de) tutulur.
🗺️ ER Diyagramı
Kimlık & Profil İlan & Operasyon İletişim & Güvenlik Finans Reklam Misafir (Faz 2)
usersid 🔑phone_number · emailrole · status · rating_avg firmsid 🔑user_id →userscompany_type · tax_number driversid 🔑user_id →users · tc_no_enclanguages · has_d2 user_devicesuser_id →users · fcm_tokendevice_os vehiclesid 🔑owner_id →users · platehas_camera · vehicle_class vehicle_job_typesvehicle_id →vehiclesjob_type documentsid 🔑entity_type + entity_idverification_status · expires job_postingsid 🔑firm_id →firmspricing_type · priceroute_waypoints JSONBscheduled_at · status job_applicationsid 🔑job_posting_id · applicantoffered_price · status job_assignments ★yeniid 🔑job_posting_id · driver · vehicleqr_code · status trips ★yeniid 🔑assignment_id →job_assignmentsstarted_at · last_lat/lng chatsid 🔑job_posting_id · firm · driverstatus messagesid 🔑chat_id →chats · is_maskedis_read · sent_at reviewsid 🔑reviewer · reviewee · ratingcomment sos_alertsid 🔑driver · lat · lng · status notifications ★yeniuser_id · channel · is_read walletsuser_id →users · balancecurrency wallet_transactionsid 🔑type · amount · service_typepsp_reference · status pricing_configkey · value · updated_by subscriptions ★yeniid 🔑firm_id · plan_keyposting_limit · postings_used guest_postings ★Faz2id 🔑contact_name · phone · emailroute · event_date · payment_refstatus · converted_firm_id ad_zoneszone_name · daily_price advertisementsid 🔑zone_id · user_id · image_urlstart/end_date · status ad_metricsad_id · impressions · clicks
Tablo sözlüğü — modül modül
👤 Kimlık & Profil
users — tek giriş noktası; rol (FIRM/DRIVER/VEHICLE_OWNER/ADMIN), SMS+e-posta doğrulama bayrakları, ortalama puan.
firms — company_type ile otel/acente/tur operatörü ayrımı (kontrol #2).
drivers — TC No şifreli (tc_no_enc), dil bilgisi, D2 bayrağı.
vehicles — plaka, kapasite, VIP sınıfı; kamera & rehber koltuğu bayrakları (okul servisi alanları).
vehicle_job_types — aracın yapabileceği iş tipleri → eşleştirme filtreleri.
user_devices — FCM token'ları; push hedeflemesi.
📋 İlan & Operasyon
job_postings — pricing_type (SABIT_FIYAT / TEKLIF_TOPLA), dinamik alanlar JSONB, waypoints, scheduled_at + tekrar günleri.
job_applications — teklif modülü burada yaşar: offered_price teklif yarışını taşır.
job_assignments ★ — iş → şoför + araç bağlama, QR kod üretimi, onay durumu.
trips ★ — sefer başlangıç/bitiş, son bilinen konum (Redis yansıması).
documents — polimorfik (USER/VEHICLE); file_expires_at poliçe/psikoteknik bitiş takibi.
💬 İletişim & Güvenlik
chats / messages — iş başına tek sohbet; is_masked ile onay öncesi kimlik gizleme (SRS 10.3).
reviews — karşılıklı 1-5 puan; iş tamamlanmadan yorum açılmaz.
sos_alerts — yalnızca SOS anı kalıcılaşır; koordinat + çözüm durumu.
notifications ★ — app içi kutu + push geçmişi; okunmamış sayacı buradan.
💰 Finans
wallets — kullanıcı başına tek cüzdan, bakiye CHECK kısıtı ile negatife düşmez.
wallet_transactions — DEPOSIT/PAYMENT/REFUND…; psp_reference Iyzico/PayTR mutabakatı için.
pricing_config — admin panelinden ilan/öne çıkarma/reklam fiyatları dinamik ayarlanır (SRS 9.4).
subscriptions ★ — abonelik paketleri; ilan kotası postings_used ile takip edilir.
📢 Reklam
ad_zones — APP_HOME_BANNER, WEB_MARKET_SIDEBAR… günlük fiyatlı.
advertisements — tarih aralıklı yayın; admin onay statusü.
ad_metrics — gösterim/tıklama sayaçları (Redis'te artar, periyodik DB'ye yazılır).
🌐 Misafir İlan (Faz 2)
guest_postings ★ — üyeliksiz akışın kalbi: iletişim + rota + tarih + ödeme referansı.
Durum makinesi: PENDING_PAYMENT → PENDING_MODERATION → PUBLISHED (→ EXPIRED / REJECTED).
İlan sahibi üye olursa: converted_firm_id ile ilgili firmaya devredilir → CONVERted.
Firma panelindeki Fırsat Radarı bu tabloyu okur; firma kiracı olarak ilanı alıp kendi ilanına dönüştürür.
🔗 SRS V5 ↔ Şema Eşleştirmesi
Bölüm bazlı birebir kontrol
SRS BölümüKarşılanan TablolarNot
3. Rolleri & Evraklarusers, firms, drivers, vehicles, documentsBelge tipleri enum; bitiş tarihleri file_expires_at
4. İlan & Filtrelemejob_postings, vehicle_job_typesDinamik alanlar dynamic_fields JSONB'de
5. Mobil Altyapıuser_devices, job_assignments(qr_code), tripsGPS konumu Redis'te; QR atamada
6. Çekirdek ERusers, firms, vehicles, documents, job_postings, job_applications, user_devicesSRS'in kendi tabloları aynen korundu
7. Reklamad_zones, advertisements, ad_metricsAynen korundu
8. Cüzdanwallets, wallet_transactions, pricing_configpsp_reference ile sağlayıcı bağımsız
10.1 Puanlamareviews (+ users.rating_avg)Rozetler rating eşiğinden hesaplanır
10.2 Ters İhalejob_postings.pricing_type, job_applications.offered_priceALTER TABLE yerine kalıcı kolon
10.3 Mesajlaşmachats, messages (+is_masked)Maskeleme kolonu eklendi
10.4 Takip & SOStrips, sos_alertsCanlı konum Redis, SOS DB
10.5 Rotajob_postings.route_waypoints, route_distance_kmMesafe API'den hesaplanıp yazılır
1.1 AboneliksubscriptionsSRS'te tablo yoktu → eklendi
Faz 2 · Üyeliksiz ilanguest_postingsSRS dışı talep → tasarım yeni tabloyla karşılandı
📦 db/schema.sql — çalıştırılabilir, TOHUM verili 🐘 PostgreSQL 16 · 22 tablo · 16 enum 🔒 KVKK: tc_no_enc şifreli, audit log önerilir