TurkeyScuba

Dalış Kayıt Defteri (Dive Logbook) — Araştırma & Tasarım Dokümanı

Hedef: Dünyadaki en gelişmiş dalış kayıt defteri sistemini tasarlamak. Tarih: 2026-02-18


1. Mevcut Platformlar ve Analizi

A. Sertifika Kuruluşu Uygulamaları

PlatformArtılarıEksileri
PADI AppeCard yönetimi, QR ile eğitim dalışı doğrulama, en büyük kullanıcı tabanıDalış bilgisayarı import yok, basit log alanları, analiz yok
MySSI65K+ dalış noktası DB, QR ile buddy paylaşımı, ekipman yönetimi (seri no, fatura, bakım), ScubaPro LogTRAK entegrasyonuBazı loglar ana ekranda görünüp logbook'ta görünmüyor

B. Dalış Bilgisayarı Üretici Uygulamaları

PlatformArtılarıEksileri
Garmin DiveOtomatik GPS giriş/çıkış, kalp atışı + kalori, 4K+ dalış noktasıKapalı ekosistem, 3. parti import yok
Shearwater Cloud10 saniyelik profil adımlama, en detaylı teknik dalış verisi, UDDF exportFotoğraf/harita yok, manuel dalış eklenemez
Suunto AppBLE + USB senkron, etkinlik zaman çizelgesi, DM5 importBasit veri, etkileşimsiz profil grafiği
ScubaPro LogTRAKO2 toksisitesi, kalp atışı, kalori, en temiz UIPaylaşım yok, fotoğraf yok, buddy/ekipman alanı yok
Oceanic+Apple Watch'u dalış bilgisayarına dönüştürür, canlı çevre verileriAbonelik modeli, sadece Apple, sadece rekreasyonel

C. Bağımsız / Evrensel Platformlar

PlatformArtılarıEksileri
SubsurfaceEn geniş bilgisayar desteği (libdivecomputer), çoklu bilgisayar birleştirme, açık kaynak, ücretsiz bulutEski UI, zayıf GPS/harita, mobilde UDDF import yok
DiveMateUSB + IR + BLE doğrudan telefonda, 170+ model, 65K+ dalış noktası, offline haritalarPremium özellikler ücretli
DiviacTıkla-doğrula log onaylama, deniz canlıları DB, 200K+ dalgıç, 10K+ merkezPADI satın aldı, geliştirici ilgisi azaldı
Diving Log 6.010 gaz CCR/trimix, en iyi masaüstü GPS/haritaSadece Windows masaüstü, ücretli
CurrentsEn modern UI, lifetime fiyatlama, hibrit offline/onlineSadece iOS, küçük kullanıcı tabanı
DiveboardVatandaş bilimi (GBIF/OBIS biyoçeşitlilik veritabanlarına katkı)Küçük kullanıcı tabanı, az özellik
OctologsBaşarım/rozet gamifikasyonu, uygulama içi mesajlaşmaYeni, küçük topluluk
SeabookAI fotoğraf bazlı tür tanımlama, 1700+ türDalış logu zayıf, deniz canlısı odaklı
WikibubblesGerçek zamanlı okyanus verileri, geçmişe dönük hava durumu otomatik doldurmaÇok yeni, küçük kullanıcı tabanı
Buddy AppSosyal dalış ağı, eğitmen doğrulama, rezervasyon sistemi, dalış dükkanı diziniNispeten yeni, sınırlı özellikler

D. Platform Karşılaştırma Matrisi

ÖzellikSubsurfaceDiving LogGarminMacDiveDiviacMySSIDiveMate
Ücretsiz✅*✅/💰
Açık Kaynak
Teknik Dalış✅✅✅✅✅✅✅✅
CCR/Rebreather
Trimix
Dalış Planlama
Sosyal Özellik
Deniz Yaşamı DB✅✅✅✅✅
Harita/GPS✅✅✅✅✅✅
Bulut Sync
Bilgisayar Desteği50+300+Garmin150+100+Sınırlı170+
Mobil UygulamaiOS

E. Kapanan Platformlar — Ders Çıkarılacak

Deepblu (Kapandı — Aralık 2023)

  • En sosyal dalış platformuydu
  • Kapanma nedeni: Kullanıcılar abonelik ödemeye isteksiz, sunucu maliyetleri arttı
  • Ders: Bulut bağımlı platformlar sürdürülebilir gelir modeli olmadan çöker. Export yapamayan kullanıcılar verilerini kaybetti.

2. Piyasada Eksik Olan Özellikler (Fırsat Alanları)

  1. Eski UI'lar — Subsurface, Diviac, divelogs.de hepsi eski görünümlü. Modern, güzel arayüz rekabet avantajı.
  2. Vendor Lock-in — Garmin sadece Garmin, Suunto sadece Suunto import eder. Bilgisayar değiştiren kullanıcılar geçmişini kaybeder.
  3. Tek birleşik platform yok — Dalgıçlar sertifika için PADI, bilgisayar logu için Garmin, analiz için Subsurface, fotoğraf için Instagram kullanıyor.
  4. Zayıf offline — Teknede/uzak adada internet yok. Deepblu'nun kapanması riski kanıtladı.
  5. Abonelik yorgunluğu — Dalgıçlar defter için tekrarlayan ödeme istemiyor.
  6. Entegre dalış planlama + loglama yok — Keşif → planlama → loglama → analiz → paylaşım tek akışta değil.
  7. Eğitmen/Merkez panosu yok — B2B+B2C model: merkez öğrencileri yönetir, dalgıç logbook'unu yönetir, kesişirler.
  8. Akıllı çevre verisi otomatik doldurma yok — Konum + tarih → hava, gelgit, su sıcaklığı, ay evresi otomatik gelsin.
  9. AI deniz canlısı tanıma logbook'a entegre değil — Seabook ayrı uygulama, logbook'a gömülü değil.
  10. Çoklu kuruluş sertifika takibi yok — PADI, SSI, CMAS, TSSF hepsi ayrı. Tek yerde birleştiren yok.
  11. Doğrulanabilir dijital dalış kimliği yok — Dalış merkezlerinin kabul edeceği, değiştirilemez dijital dalgıç pasaportu.
  12. Rebreather/teknik dalış mobilde zayıf — Sadece masaüstü uygulamalar CCR/trimix destekliyor.
  13. Dalış sonrası değerlendirme araçları yok — Yapılandırılmış debrief kontrol listesi, beceri değerlendirmesi, eğitmen geri bildirimi.
  14. Bölgesel içerik yok — Yerel düzenlemeler, izin gereksinimleri, deniz parkı ücretleri, mevsimsel koşullar.

3. TurkeyScuba Dive Logbook — Özellik Listesi

3.1 Temel Dalış Kayıt Alanları

Dalış Kimliği

  • Dalış numarası (otomatik artan)
  • Tarih ve saat (giriş/çıkış)
  • Dalış süresi (toplam, dip süresi ayrı)
  • Yüzey aralığı (bir önceki dalıştan)
  • Dalış tipi: rekreasyonel, teknik, serbest dalış (freediving), ticari, bilimsel, askeri, eğitim
  • Dalış stili: tekne, kıyı, akıntı, gece, buz, mağara, batık, duvar, muck, derin, yükseklik
  • Dalış amacı: eğlence, eğitim, fotoğrafçılık, araştırma, kurtarma, bakım
  • Nefes alma modu: açık devre (OC), CCR, pSCR, serbest dalış
  • Trip/seyahat gruplaması — çoklu dalışı bir gezi altında toplama

Konum

  • Ülke, bölge, dalış noktası adı
  • GPS koordinatları (giriş/çıkış ayrı ayrı)
  • Dalış noktası ilişkilendirme (platformdaki dive_sites tablosuyla FK)
  • Haritada görsel işaretleme

Derinlik & Profil

  • Maksimum derinlik (m)
  • Ortalama derinlik (m)
  • Planlanan derinlik (m)
  • Derinlik profili (zaman serisi — bilgisayardan import)
  • Yükseklik düzeltmesi (rakım dalışı için)

Gaz & Hava Tüketimi

  • Tüp tipi (çelik/alüminyum) ve hacmi (L)
  • Gaz karışımı (hava/nitrox/trimix) — O2%, He%
  • Başlangıç basıncı (bar)
  • Bitiş basıncı (bar)
  • SAC rate (hesaplanır)
  • RMV (hesaplanır)
  • Toplam tüketim (L)
  • Çoklu tüp desteği (teknik dalış — dalış başına 10+ gaz)
  • Gaz değişim noktaları ve zamanları
  • Stage/bailout tüpleri
  • Gaz kullanım tipi: dip, deco, seyahat, bailout, diluent

CCR/Rebreather Özel Verileri

  • Setpoint değerleri ve değişim zamanları
  • ppO2 değerleri (3 sensörden)
  • Diluent gaz bilgisi
  • Bailout gaz bilgisi
  • Diluent → Bailout geçişi
  • Scrubber kullanım süresi / kapasitesi
  • Loop hacmi

Dekompresyon

  • Dekompresyon algoritması (Bühlmann ZH-L16C, VPM-B, RGBM)
  • Gradient faktörleri (GF Low / GF High)
  • NDL (no-deco limit) — dalış boyunca
  • Güvenlik durağı (derinlik/süre, uyum kaydı)
  • Deco durakları (derinlik/süre)
  • Tavan (ceiling) profili
  • CNS% (Merkezi Sinir Sistemi oksijen toksisitesi)
  • OTU (Oxygen Toxicity Units)
  • Doku doygunluk verileri
  • Kullanılan tablo/algoritma

Sıcaklık & Koşullar

  • Hava sıcaklığı
  • Yüzey su sıcaklığı
  • Dip su sıcaklığı
  • Termoklin derinliği
  • Görüş mesafesi (m)
  • Akıntı (yok/hafif/orta/güçlü)
  • Dalga yüksekliği
  • Rüzgar hızı/yönü
  • Gelgit durumu
  • Hava durumu
  • Ay evresi (otomatik)
  • Su tipi: tatlı su, tuzlu su, acımsı (brackish)
  • Barometre basıncı
  • UV indeksi
  • Otomatik çevre verisi doldurma — konum + tarih → API'den hava, gelgit, su sıcaklığı çekilir

Güvenlik Kaydı

  • Güvenlik durağı uyumu (evet/hayır)
  • Hızlı çıkış (evet/hayır)
  • Deko ihlali (evet/hayır)
  • Aşım süresi (varsa)
  • Olay/kaza raporu
  • Buddy sistemi uyumu
  • Dalış öncesi kontrol listesi (pre-dive checklist)
  • Dalış planı vs gerçekleşen karşılaştırma

Fizyolojik Veriler

  • Kümülatif CNS%
  • Kümülatif OTU
  • Tekrarlayan dalışlarda azot yüklenmesi
  • Uçuşa/yüksekliğe çıkma için bekleme süresi
  • Kalp atışı (bilgisayar destekliyorsa)

3.2 Ekipman Yönetimi

  • BCD: marka, model, beden, entegre ağırlık cepleri
  • Regülatör: marka, model, son bakım tarihi, sonraki bakım tarihi
  • Dalış bilgisayarı: marka, model, firmware sürümü, pil durumu
  • Dalış elbisesi: tip (wetsuit/drysuit/skin), kalınlık, başlık, eldiven, bot
  • Ağırlık: toplam ağırlık, tip (kemer/entegre/ayak bileği), denge kontrolü
  • Kamera: kamera tipi, housing, flaş, lens
  • Diğer: fener, SMB, reel, bıçak, pusula, yazı tahtası
  • Seri numarası takibi (her ekipman parçası)
  • Fatura/makbuz ekleme (satın alma kanıtı)
  • Bakım hatırlatıcıları (regülatör servisi, vb.)
  • Dalış sayacı (her ekipman kaç dalışta kullanıldı)
  • Ekipman kitleri (sık kullanılan set'leri kaydetme)

3.3 Buddy & Sosyal

Buddy Sistemi

  • Buddy adı, sertifika seviyesi, iletişim bilgisi
  • Eğitmen/divemaster adı, sertifika numarası, kuruluş
  • Dijital imza/QR doğrulama (buddy veya eğitmen onayı — yeşil tik)
  • Dalış merkezi adı, konum, derecelendirme
  • Dalış grubundaki diğer kişiler
  • Profil bazlı buddy listesi (sık dalış yapılan kişiler)
  • Dalış daveti (buddy'yi dalışa davet etme)
  • Buddy değerlendirmesi
  • Birlikte yapılan dalış geçmişi

Topluluk Özellikleri

  • Takip sistemi (follow/following)
  • Dalış beğenme (like)
  • Dalış yorumları (iç içe — nested comments)
  • Feed/akış (takip edilen kişilerin dalışları)
  • Mesajlaşma
  • Grup/kulüp oluşturma
  • Etkinlik planlama
  • Dalış hikayesi paylaşımı (storytelling — blog benzeri)
  • 3 seviye gizlilik: public / friends / private

3.4 Deniz Canlıları

  • Tür adı (yaygın/bilimsel)
  • Fotoğraf
  • Miktar/boyut tahmini
  • Davranış notu
  • AI fotoğraf bazlı tür tanımlama (fotoğraf yükle → otomatik tür önerisi)
  • Tür veritabanı (binlerce tür profili, fotoğraf, habitat bilgisi)
  • Mercan sağlığı, yosun seviyesi, su berraklığı
  • Nadir gözlemler işareti
  • Kişisel "görülen türler" listesi (life list)
  • Biyoçeşitlilik katkısı (anonim veri bilimsel veritabanlarına gönderilebilir — GBIF/OBIS)

Çevre Koruma Raporu

  • Resif sağlığı değerlendirmesi (1-5)
  • Mercan ağartması gözlemi (yok/hafif/orta/şiddetli)
  • Deniz çöpü raporu (plastik, ağ, cam, vb.)
  • Toplanan çöp miktarı
  • İstilacı tür bildirimi
  • Çevre koruma etkinliği katılımı
  • Karbon ayak izi hesaplama (seyahat dahil)
  • Reef Check / Project AWARE entegrasyonu

3.5 Medya

  • Fotoğraf ekleme (dalış profili zaman çizelgesine bağlı, GPS etiketli)
  • Video ekleme (kısa klipler)
  • 360 derece fotoğraf desteği
  • Fotoğraf etiketleme (tür, ekipman, buddy)
  • Fotoğraf sıkıştırma ve optimize depolama
  • Galeri görünümü
  • Filigran ekleme (opsiyonel)
  • Sosyal medya paylaşımı
  • Serbest metin notları + özel notlar (sadece kullanıcı görebilir)
  • Kişisel derecelendirme (1-5 yıldız) + zorluk derecelendirmesi (1-5)
  • Cloudflare R2 depolama (mevcut altyapıyla uyumlu)

3.6 Sertifika Takibi (Çoklu Kuruluş)

  • PADI, SSI, CMAS/TSSF, NAUI, BSAC, GUE, TDI/SDI ve diğerleri
  • Sertifika adı, seviyesi, numarası, tarih
  • eCard/belge fotoğrafı yükleme
  • Sigorta bilgisi (DAN, vb.)
  • İlk yardım/CPR sertifikaları
  • TSSF Yetki Belgesi doğrulama (Türkiye'ye özel)

3.7 İstatistik & Analiz

  • Toplam dalış sayısı, toplam süre, toplam dip zamanı
  • Maks/ort/min derinlik istatistikleri
  • SAC rate trendi (30 gün, 6 ay, ömür boyu)
  • Hava tüketimi pattern görselleştirmesi
  • En çok dalınan noktalar
  • Aylık/yıllık dalış sıklığı grafikleri
  • Sıcaklık ve görüş trendleri
  • Ülke/bölge bazlı dalış haritası (heatmap)
  • Buddy bazlı istatistikler
  • Ekipman kullanım istatistikleri
  • Dalış tipi dağılımı (pasta grafik)
  • Kümülatif doku yüklemesi takibi (çoklu dalış günlerinde)

3.8 Gamifikasyon & Başarımlar

  • Rozet sistemi:
    • İlk dalış, 10/25/50/100/250/500/1000. dalış
    • İlk gece dalışı, ilk batık dalışı, ilk akıntı dalışı
    • Derinlik kilometre taşları (20m, 30m, 40m)
    • Coğrafi başarımlar (5/10/20 farklı ülke)
    • Tür başarımları (50/100/200 farklı tür gözlemi)
    • Sezonluk başarımlar (her mevsimde dalış)
    • Topluluk başarımları (10 buddy dalışı, 5 deniz temizliği)
  • Seviye sistemi (SSI tarzı: OW → AOW → Rescue → Master → vb.)
  • Liderlik tablosu (isteğe bağlı, anonim veya açık)

3.9 Güvenlik & Acil Durum

  • Acil durum iletişim kişileri
  • Kan grubu
  • Tıbbi durumlar (alerji, ilaç, kronik hastalık)
  • Sigorta bilgisi ve poliçe numarası
  • En yakın basınç odası bulucu (harita üzerinde)
  • DAN acil protokolleri (hızlı erişim)
  • Tıbbi bilgi paylaşımı (dalış merkezine QR ile)

3.10 Dalış Bilgisayarı Entegrasyonu

  • UDDF import/export (evrensel standart)
  • Garmin FIT import
  • Suunto SML/SDE import
  • Shearwater XML import
  • Subsurface XML import
  • CSV import (genel)
  • divelogs.de DLD import
  • libdivecomputer entegrasyonu (gelecekte — 140+ model)
  • Manuel giriş (bilgisayar olmadan)
  • Çoklu bilgisayar birleştirme (aynı dalışta 2 bilgisayar verisi)

3.11 Dalış Planlama (Logbook Entegre)

  • Dalış öncesi plan oluşturma
  • Mevcut hava hesaplama aracı entegrasyonu (DECO 2000)
  • Dekompresyon planlama (Bühlmann ZH-L16C + GF, VPM-B)
  • Çoklu seviye dalış planlama
  • Tekrarlayan dalış planlama (yüzey aralığı hesabı)
  • Gaz tüketimi hesaplama
  • Minimum gaz hesaplama (Rule of Thirds, Rock Bottom)
  • Bailout gaz planlama (CCR)
  • Runtime tablosu oluşturma
  • Dalış planı yazdırma
  • Rakımda dalış düzeltmesi
  • EAD (Equivalent Air Depth) hesaplama
  • MOD (Maximum Operating Depth) hesaplama
  • END (Equivalent Narcotic Depth) hesaplama
  • Best Mix hesaplama
  • Plan şablonları (kaydet ve tekrar kullan)
  • Dalış noktası koşulları kontrolü (gerçek zamanlı çevre verileri)
  • Paketleme kontrol listesi
  • Plan → Log dönüşümü (planlanan dalışı otomatik log taslağına çevir)

3.12 Offline-First Mimari

  • Tüm loglama offline çalışır
  • Fotoğraf/video offline kaydedilir, internet gelince senkronize olur
  • Çakışma çözümü (aynı log iki cihazda düzenlenirse)
  • PWA desteği (mobilde uygulama gibi çalışır)
  • Local-first veritabanı (IndexedDB veya SQLite WASM)

3.13 Eğitmen / Dalış Merkezi Paneli (B2B)

  • Öğrenci dalış loglarını görüntüleme ve onaylama
  • Eğitim dalışı değerlendirme formu
  • Beceri kontrol listesi (her eğitim dalışı için)
  • Dalış sonrası debrief şablonu
  • Sertifika ilerlemesi takibi
  • Ekipman kiralama takibi
  • Grup dalış yönetimi

3.14 Bölgesel İçerik (Türkiye Özel)

  • TSSF düzenlemeleri ve gereksinimleri
  • Deniz parkı izin/ücret bilgileri
  • Mevsimsel koşullar takvimi
  • Yasak bölgeler haritası
  • Türkiye dalış noktaları veritabanı (mevcut)

3.15 Bildirim & Hatırlatma Sistemi

  • Ekipman bakım hatırlatması (regülatör servisi, tüp testi, pil değişimi)
  • Sertifika süresi dolmak üzere uyarısı (CPR, ilk yardım)
  • Tıbbi muayene hatırlatması
  • Buddy isteği bildirimi
  • Dalış doğrulama bildirimi (buddy onayladı)
  • Dalış beğeni/yorum bildirimi
  • Takip bildirimi
  • Başarım açıldı bildirimi
  • Sigorta süresi dolmak üzere uyarısı

3.16 AI & Akıllı Özellikler

  • AI destekli deniz türü teşhisi (fotoğraf ile)
  • Akıllı dalış önerisi (hava/gelgit/görüş/deneyim seviyesine göre)
  • SAC rate tahmin modeli (geçmiş verilere göre)
  • Anomali tespiti ve güvenlik uyarıları (hızlı çıkış, deko ihlali)
  • Otomatik dalış tipi sınıflama
  • Doğal dil ile dalış notu oluşturma
  • 3D dalış profili görselleştirme (GPS + derinlik verisiyle)

3.17 Teknik Özellikler

  • Metrik/imperial birim değişimi
  • Karanlık mod (dark mode)
  • Çoklu dil desteği (en az 10 dil)
  • GDPR uyumlu — veri yedekleme, geri yükleme, hesap silme, veri taşıma hakkı
  • End-to-end şifreleme (tıbbi veriler için)
  • 2FA (iki faktörlü doğrulama — mevcut)
  • Rol bazlı erişim (dalgıç, eğitmen, merkez yöneticisi, admin)
  • Import duplikasyon önleme (dosya hash kontrolü)

3.18 Veri Taşınabilirliği & Format Desteği

FormatTipYön
UDDFXML — Evrensel standartImport + Export
Garmin FITBinary — Garmin cihazlarImport
Suunto SMLXML — Suunto cihazlarImport
Shearwater XMLXML — Shearwater cihazlarImport
Subsurface XMLXML — SubsurfaceImport + Export
CSVDüz metin — GenelImport + Export
divelogs.de DLDZIP+XMLImport
DAN DL7DAN araştırma formatıImport
Mares MDBMares cihazlarImport
JSONTurkeyScuba nativeExport
PDFBaskı/paylaşımExport
HTMLWeb paylaşımıExport
ExcelTablo analizExport
Google Earth KML/KMZHaritaExport
GPXGPS izleriExport

4. Veritabanı Şeması (Supabase PostgreSQL)

4.1 Ana Tablolar

-- =============================================
-- DALIŞLAR (Ana tablo)
-- =============================================
CREATE TABLE dive_logs (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  dive_number INTEGER, -- kullanıcı bazlı sıra numarası
  trip_id UUID REFERENCES trips(id) ON DELETE SET NULL,

  -- Tarih & Süre
  dive_date DATE NOT NULL,
  time_in TIMESTAMPTZ,
  time_out TIMESTAMPTZ,
  duration_min NUMERIC(6,1),
  bottom_time_min NUMERIC(6,1), -- dip süresi (toplam süreden ayrı)
  surface_interval_min INTEGER, -- bir önceki dalıştan

  -- Konum
  dive_site_id UUID REFERENCES dive_sites(id),
  custom_site_name TEXT, -- DB'de olmayan nokta için
  entry_point GEOGRAPHY(POINT, 4326), -- PostGIS giriş koordinatı
  exit_point GEOGRAPHY(POINT, 4326), -- PostGIS çıkış koordinatı
  country_code CHAR(2),
  region TEXT,

  -- Derinlik
  max_depth_m NUMERIC(5,1),
  avg_depth_m NUMERIC(5,1),
  planned_depth_m NUMERIC(5,1),
  altitude_m INTEGER DEFAULT 0, -- yükseklik dalışı için

  -- Gaz (birincil tüp — çoklu tüp için dive_log_tanks)
  tank_type TEXT, -- 'steel', 'aluminum'
  tank_volume_l NUMERIC(4,1),
  gas_mix TEXT DEFAULT 'air', -- 'air', 'ean32', 'ean36', 'trimix'
  o2_percent NUMERIC(4,1) DEFAULT 21,
  he_percent NUMERIC(4,1) DEFAULT 0,
  start_pressure_bar INTEGER,
  end_pressure_bar INTEGER,
  sac_rate NUMERIC(5,1), -- hesaplanan SAC
  rmv NUMERIC(5,1), -- hesaplanan RMV

  -- Nefes alma modu & dalış amacı
  breathing_mode TEXT DEFAULT 'open_circuit', -- 'open_circuit', 'ccr', 'pscr', 'freediving'
  dive_purpose TEXT, -- 'fun', 'training', 'photography', 'research', 'rescue', 'maintenance'
  dive_style TEXT, -- 'boat', 'shore', 'drift', 'night', 'ice', 'cave', 'wreck', 'wall', 'muck', 'deep', 'altitude'
  water_type TEXT, -- 'salt', 'fresh', 'brackish'

  -- Dekompresyon
  deco_algorithm TEXT, -- 'buhlmann_zhl16c', 'vpm_b', 'rgbm'
  gf_low INTEGER, -- gradient factor low (0-100)
  gf_high INTEGER, -- gradient factor high (0-100)
  ndl_min INTEGER,
  safety_stop_depth_m NUMERIC(3,1),
  safety_stop_min NUMERIC(3,1),
  safety_stop_performed BOOLEAN DEFAULT TRUE,
  deco_stops_performed BOOLEAN DEFAULT FALSE,
  total_deco_min INTEGER,
  cns_percent NUMERIC(5,2),
  otu NUMERIC(7,2),
  deco_table TEXT, -- 'deco2000', 'padi_rdp', vb.

  -- Koşullar
  air_temp_c NUMERIC(4,1),
  surface_water_temp_c NUMERIC(4,1),
  bottom_water_temp_c NUMERIC(4,1),
  thermocline_depth_m NUMERIC(4,1),
  visibility_m NUMERIC(4,1),
  current TEXT, -- 'none', 'mild', 'moderate', 'strong'
  surge TEXT, -- 'none', 'mild', 'moderate', 'strong'
  wave_height_m NUMERIC(3,1),
  wind_speed_kmh NUMERIC(4,1),
  wind_direction TEXT,
  weather TEXT, -- 'sunny', 'cloudy', 'rainy', 'overcast'
  tide TEXT, -- 'high', 'low', 'incoming', 'outgoing', 'slack'
  moon_phase TEXT, -- otomatik hesaplanır
  barometer_hpa NUMERIC(6,1),
  uv_index SMALLINT,

  -- Dalış tipi & aktivite
  dive_type TEXT[] DEFAULT '{}', -- ['recreational', 'night', 'drift', 'wreck', 'cave', 'ice', 'training']
  activity TEXT[] DEFAULT '{}', -- ['photography', 'videography', 'research', 'cleanup', 'instruction']
  entry_method TEXT, -- 'shore', 'boat', 'zodiac'
  entry_technique TEXT, -- 'giant_stride', 'back_roll', 'seated'

  -- Elbise & Ağırlık
  suit_type TEXT, -- 'wetsuit', 'drysuit', 'skin', 'none'
  suit_thickness_mm NUMERIC(3,1),
  hood BOOLEAN DEFAULT FALSE,
  gloves BOOLEAN DEFAULT FALSE,
  boots BOOLEAN DEFAULT FALSE,
  weight_total_kg NUMERIC(4,1),
  weight_type TEXT, -- 'belt', 'integrated', 'ankle', 'mixed'
  buoyancy_check BOOLEAN,

  -- Buddy & Merkez
  buddy_id UUID REFERENCES profiles(id),
  buddy_name TEXT, -- platformda olmayan buddy için
  instructor_id UUID REFERENCES profiles(id),
  instructor_name TEXT,
  dive_center_id UUID REFERENCES dive_schools(id),
  custom_dive_center_name TEXT, -- platformda olmayan merkez için

  -- Güvenlik
  had_safety_issue BOOLEAN DEFAULT FALSE,
  safety_issue_description TEXT,
  rapid_ascent BOOLEAN DEFAULT FALSE,
  missed_deco BOOLEAN DEFAULT FALSE,

  -- Değerlendirme
  rating SMALLINT CHECK (rating BETWEEN 1 AND 5),
  difficulty_rating SMALLINT CHECK (difficulty_rating BETWEEN 1 AND 5),
  notes TEXT,
  private_notes TEXT, -- sadece kullanıcının görebileceği notlar

  -- Doğrulama
  verified_by UUID REFERENCES profiles(id), -- buddy/eğitmen onayı
  verified_at TIMESTAMPTZ,
  verification_method TEXT, -- 'qr', 'digital_signature', 'manual'

  -- Bilgisayar import
  computer_brand TEXT,
  computer_model TEXT,
  import_format TEXT, -- 'uddf', 'fit', 'sml', 'shearwater_xml', 'manual'
  original_file_hash TEXT, -- kaynak dosya hash (duplikasyon önleme)
  raw_import_data JSONB, -- orijinal import verisi (yedek)

  -- Çevre verisi otomatik doldurma
  env_data_auto_filled BOOLEAN DEFAULT FALSE,
  env_data_source TEXT, -- 'openmeteo', 'stormglass', vb.

  -- Gizlilik (3 seviye: public / friends / private)
  visibility TEXT NOT NULL DEFAULT 'public'
    CHECK (visibility IN ('public', 'friends', 'private')),
  -- public  → herkes görür
  -- friends → sadece takipçiler (user_follows) görür
  -- private → sadece sahibi görür
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now(),
  deleted_at TIMESTAMPTZ -- soft delete
);

-- İndeksler
CREATE INDEX idx_dive_logs_user_id ON dive_logs(user_id);
CREATE INDEX idx_dive_logs_dive_date ON dive_logs(dive_date DESC);
CREATE INDEX idx_dive_logs_dive_site_id ON dive_logs(dive_site_id);
CREATE INDEX idx_dive_logs_entry_point ON dive_logs USING GIST(entry_point);
CREATE INDEX idx_dive_logs_deleted_at ON dive_logs(deleted_at) WHERE deleted_at IS NULL;
CREATE INDEX idx_dive_logs_visibility ON dive_logs(visibility);


-- =============================================
-- DECO DURAKLARI (dalış başına çoklu durak)
-- =============================================
CREATE TABLE dive_log_deco_stops (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  depth_m NUMERIC(4,1) NOT NULL,
  duration_min NUMERIC(5,1) NOT NULL,
  sort_order SMALLINT DEFAULT 0,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_deco_stops_dive_log ON dive_log_deco_stops(dive_log_id);


-- =============================================
-- ÇOKLU TÜP (teknik dalışlar için)
-- =============================================
CREATE TABLE dive_log_tanks (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  tank_number SMALLINT NOT NULL DEFAULT 1,
  tank_type TEXT, -- 'steel', 'aluminum'
  tank_volume_l NUMERIC(4,1),
  gas_mix TEXT DEFAULT 'air',
  o2_percent NUMERIC(4,1) DEFAULT 21,
  he_percent NUMERIC(4,1) DEFAULT 0,
  start_pressure_bar INTEGER,
  end_pressure_bar INTEGER,
  switch_depth_m NUMERIC(4,1), -- gaz geçiş derinliği
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_tanks_dive_log ON dive_log_tanks(dive_log_id);


-- =============================================
-- EKİPMAN
-- =============================================
CREATE TABLE equipment (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  category TEXT NOT NULL, -- 'bcd', 'regulator', 'computer', 'suit', 'mask', 'fins', 'camera', 'light', 'smb', 'other'
  brand TEXT,
  model TEXT,
  serial_number TEXT,
  purchase_date DATE,
  purchase_price NUMERIC(10,2),
  currency CHAR(3) DEFAULT 'TRY',
  notes TEXT,
  image_url TEXT, -- R2'de fotoğraf
  invoice_url TEXT, -- R2'de fatura
  is_active BOOLEAN DEFAULT TRUE,
  total_dives INTEGER DEFAULT 0, -- otomatik güncellenen sayaç
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now(),
  deleted_at TIMESTAMPTZ
);

CREATE INDEX idx_equipment_user_id ON equipment(user_id);


-- =============================================
-- EKİPMAN BAKIM GEÇMİŞİ
-- =============================================
CREATE TABLE equipment_maintenance (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  equipment_id UUID NOT NULL REFERENCES equipment(id) ON DELETE CASCADE,
  maintenance_type TEXT NOT NULL, -- 'service', 'repair', 'inspection', 'battery_change'
  description TEXT,
  performed_at DATE NOT NULL,
  performed_by TEXT, -- servis merkezi adı
  cost NUMERIC(10,2),
  currency CHAR(3) DEFAULT 'TRY',
  next_maintenance_date DATE, -- hatırlatıcı
  next_maintenance_dives INTEGER, -- X dalış sonra bakım
  receipt_url TEXT, -- R2'de makbuz
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_maintenance_equipment ON equipment_maintenance(equipment_id);


-- =============================================
-- DALIŞ-EKİPMAN İLİŞKİSİ
-- =============================================
CREATE TABLE dive_log_equipment (
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  equipment_id UUID NOT NULL REFERENCES equipment(id) ON DELETE CASCADE,
  PRIMARY KEY (dive_log_id, equipment_id)
);


-- =============================================
-- EKİPMAN KİTLERİ (sık kullanılan setler)
-- =============================================
CREATE TABLE equipment_kits (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  name TEXT NOT NULL, -- 'Yaz seti', 'Teknik dalış seti'
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE equipment_kit_items (
  kit_id UUID NOT NULL REFERENCES equipment_kits(id) ON DELETE CASCADE,
  equipment_id UUID NOT NULL REFERENCES equipment(id) ON DELETE CASCADE,
  PRIMARY KEY (kit_id, equipment_id)
);


-- =============================================
-- DENİZ CANLILARI GÖZLEMLERİ
-- =============================================
CREATE TABLE dive_log_species (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  species_id UUID REFERENCES marine_species(id), -- varsa DB'deki tür
  custom_species_name TEXT, -- DB'de yoksa
  quantity TEXT, -- 'single', 'few', 'school', 'many'
  size_estimate TEXT, -- 'small', 'medium', 'large'
  behavior_notes TEXT,
  photo_url TEXT,
  ai_identified BOOLEAN DEFAULT FALSE, -- AI ile tanımlandı mı
  ai_confidence NUMERIC(3,2), -- 0.00-1.00 güven skoru
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_species_dive_log ON dive_log_species(dive_log_id);


-- =============================================
-- DENİZ TÜRLERİ REFERANS TABLOSU
-- =============================================
CREATE TABLE marine_species (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  common_name_tr TEXT,
  common_name_en TEXT,
  scientific_name TEXT NOT NULL,
  family TEXT,
  category TEXT, -- 'fish', 'invertebrate', 'mammal', 'reptile', 'coral', 'plant'
  habitat TEXT[], -- ['reef', 'pelagic', 'sand', 'cave', 'wreck']
  depth_range_min_m INTEGER,
  depth_range_max_m INTEGER,
  conservation_status TEXT, -- IUCN: 'LC', 'NT', 'VU', 'EN', 'CR'
  image_url TEXT,
  description_tr TEXT,
  description_en TEXT,
  regions TEXT[], -- ['mediterranean', 'red_sea', 'caribbean', 'indo_pacific']
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_marine_species_name ON marine_species(scientific_name);


-- =============================================
-- SERTİFİKALAR
-- =============================================
CREATE TABLE certifications (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  agency TEXT NOT NULL, -- 'PADI', 'SSI', 'CMAS', 'TSSF', 'NAUI', 'BSAC', 'GUE', 'TDI', 'SDI'
  certification_name TEXT NOT NULL, -- 'Open Water Diver', 'Advanced', vb.
  certification_level TEXT, -- '1_star', '2_star', '3_star' (CMAS) veya 'ow', 'aow', 'rescue', 'dm', 'instructor'
  certification_number TEXT,
  issue_date DATE,
  expiry_date DATE, -- varsa (CPR/First Aid gibi)
  instructor_name TEXT,
  instructor_number TEXT,
  dive_center TEXT,
  card_front_url TEXT, -- R2'de eCard fotoğrafı
  card_back_url TEXT,
  is_verified BOOLEAN DEFAULT FALSE,
  verified_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_certifications_user_id ON certifications(user_id);


-- =============================================
-- MEDYA (fotoğraf/video)
-- =============================================
CREATE TABLE dive_log_media (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  media_type TEXT NOT NULL, -- 'photo', 'video'
  url TEXT NOT NULL, -- R2 URL
  thumbnail_url TEXT,
  caption TEXT,
  taken_at TIMESTAMPTZ, -- fotoğrafın çekildiği an
  depth_m NUMERIC(5,1), -- fotoğrafın çekildiği derinlik
  location GEOGRAPHY(POINT, 4326), -- fotoğrafın GPS koordinatı
  file_size_bytes BIGINT,
  width INTEGER,
  height INTEGER,
  sort_order SMALLINT DEFAULT 0,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_media_dive_log ON dive_log_media(dive_log_id);


-- =============================================
-- BAŞARIMLAR / ROZETLER
-- =============================================
CREATE TABLE achievements (
  id TEXT PRIMARY KEY, -- 'first_dive', 'dive_100', 'night_owl', 'globe_trotter_10'
  name_key TEXT NOT NULL, -- i18n çeviri anahtarı
  description_key TEXT NOT NULL,
  icon TEXT NOT NULL, -- ikon adı veya URL
  category TEXT NOT NULL, -- 'milestone', 'depth', 'geography', 'species', 'community', 'seasonal'
  threshold INTEGER, -- eşik değeri (100. dalış için 100)
  sort_order SMALLINT DEFAULT 0
);

CREATE TABLE user_achievements (
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  achievement_id TEXT NOT NULL REFERENCES achievements(id),
  unlocked_at TIMESTAMPTZ DEFAULT now(),
  dive_log_id UUID REFERENCES dive_logs(id), -- rozeti tetikleyen dalış
  PRIMARY KEY (user_id, achievement_id)
);

CREATE INDEX idx_user_achievements_user ON user_achievements(user_id);


-- =============================================
-- ACİL DURUM & TIBBİ BİLGİ
-- =============================================
CREATE TABLE emergency_info (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE UNIQUE,
  blood_type TEXT, -- 'A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-'
  allergies TEXT[],
  medications TEXT[],
  medical_conditions TEXT[],
  insurance_provider TEXT,
  insurance_policy_number TEXT,
  insurance_expiry DATE,
  emergency_contact_1_name TEXT,
  emergency_contact_1_phone TEXT,
  emergency_contact_1_relation TEXT,
  emergency_contact_2_name TEXT,
  emergency_contact_2_phone TEXT,
  emergency_contact_2_relation TEXT,
  physician_name TEXT,
  physician_phone TEXT,
  notes TEXT,
  share_with_dive_center BOOLEAN DEFAULT FALSE, -- QR ile merkeze paylaşım
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);


-- =============================================
-- BASINÇ ODALARI (hiperbarik merkezler)
-- =============================================
CREATE TABLE hyperbaric_chambers (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL,
  location GEOGRAPHY(POINT, 4326) NOT NULL,
  address TEXT,
  city TEXT,
  country_code CHAR(2),
  phone TEXT,
  phone_emergency TEXT,
  is_24h BOOLEAN DEFAULT FALSE,
  notes TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_chambers_location ON hyperbaric_chambers USING GIST(location);


-- =============================================
-- DALIŞA DAVET / BUDDY İSTEKLERİ
-- =============================================
CREATE TABLE dive_invitations (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  inviter_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  invitee_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  dive_date DATE NOT NULL,
  dive_site_id UUID REFERENCES dive_sites(id),
  message TEXT,
  status TEXT DEFAULT 'pending', -- 'pending', 'accepted', 'declined'
  created_at TIMESTAMPTZ DEFAULT now(),
  responded_at TIMESTAMPTZ
);

CREATE INDEX idx_invitations_invitee ON dive_invitations(invitee_id, status);


-- =============================================
-- SEYAHAT / TRIP GRUPLAMA
-- =============================================
CREATE TABLE trips (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  name TEXT NOT NULL, -- 'Kaş 2026', 'Kızıldeniz Turu'
  description TEXT,
  start_date DATE,
  end_date DATE,
  location TEXT,
  country_code CHAR(2),
  cover_image_url TEXT,
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now(),
  deleted_at TIMESTAMPTZ
);

CREATE INDEX idx_trips_user_id ON trips(user_id);


-- =============================================
-- SERTİFİKA KURULUŞLARI (referans)
-- =============================================
CREATE TABLE certification_agencies (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL, -- 'PADI', 'SSI', 'CMAS', 'TSSF', 'NAUI', 'BSAC', 'GUE', 'TDI'
  full_name TEXT,
  logo_url TEXT,
  website_url TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE certification_levels (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  agency_id UUID NOT NULL REFERENCES certification_agencies(id),
  name TEXT NOT NULL, -- 'Open Water Diver', 'Advanced', 'Rescue', vb.
  category TEXT, -- 'recreational', 'technical', 'professional', 'specialty'
  sort_order SMALLINT DEFAULT 0,
  min_age SMALLINT,
  min_dives_required SMALLINT,
  description TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_cert_levels_agency ON certification_levels(agency_id);


-- =============================================
-- TÜP (TANK) YÖNETİMİ (ekipmandan ayrı)
-- =============================================
CREATE TABLE tanks (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  name TEXT, -- 'Ana tüp', 'Stage 1'
  material TEXT NOT NULL, -- 'steel', 'aluminum', 'carbon'
  volume_l NUMERIC(5,2) NOT NULL,
  working_pressure_bar NUMERIC(5,1) NOT NULL,
  test_pressure_bar NUMERIC(5,1),
  serial_number TEXT,
  valve_type TEXT, -- 'din', 'yoke', 'manifold'
  last_hydro_test DATE,
  hydro_test_interval_years SMALLINT DEFAULT 5,
  last_visual_inspection DATE,
  visual_inspection_interval_months SMALLINT DEFAULT 12,
  status TEXT DEFAULT 'active', -- 'active', 'condemned', 'retired'
  notes TEXT,
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_tanks_user_id ON tanks(user_id);


-- =============================================
-- DALIŞ PROFİLİ — ZAMAN SERİSİ VERİLERİ
-- =============================================
CREATE TABLE dive_profile_samples (
  id BIGSERIAL PRIMARY KEY,
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  sample_time_sec INTEGER NOT NULL, -- dalış başlangıcından itibaren saniye
  depth_m NUMERIC(6,2),
  temperature_c NUMERIC(5,2),
  tank_pressure_bar NUMERIC(5,1),
  heartrate_bpm SMALLINT,
  ndl_sec INTEGER, -- No Deco Limit kalan
  ceiling_m NUMERIC(5,2), -- deko tavanı
  tts_sec INTEGER, -- Time To Surface
  setpoint NUMERIC(3,2), -- CCR setpoint
  ppo2_sensor1 NUMERIC(3,2), -- CCR O2 sensör 1
  ppo2_sensor2 NUMERIC(3,2),
  ppo2_sensor3 NUMERIC(3,2),
  cns_percent NUMERIC(5,2),
  otu NUMERIC(7,2),
  bearing SMALLINT, -- pusula yönü (0-360)
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_profile_dive_time ON dive_profile_samples(dive_log_id, sample_time_sec);


-- =============================================
-- DALIŞ OLAYLARI (events)
-- =============================================
CREATE TABLE dive_events (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  event_time_sec INTEGER NOT NULL,
  event_type TEXT NOT NULL,
  -- event_type değerleri:
  -- gas_switch, safety_stop_begin, safety_stop_end,
  -- deco_stop_begin, deco_stop_end, bookmark, alarm,
  -- heading, surface, ascent_warning, deco_violation,
  -- po2_warning, low_battery, low_gas, bailout_switch
  event_value TEXT,
  event_description TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_events_dive_log ON dive_events(dive_log_id);


-- =============================================
-- BUDDY'LER (platformda kayıtlı olmayan)
-- =============================================
CREATE TABLE buddies (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  buddy_user_id UUID REFERENCES profiles(id), -- kayıtlı kullanıcı ise
  buddy_name TEXT NOT NULL,
  buddy_email TEXT,
  buddy_certification TEXT,
  buddy_agency TEXT,
  notes TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_buddies_user_id ON buddies(user_id);


-- =============================================
-- DALIŞ-BUDDY İLİŞKİSİ (junction table)
-- =============================================
CREATE TABLE dive_buddies (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  buddy_id UUID REFERENCES buddies(id),
  buddy_user_id UUID REFERENCES profiles(id),
  role TEXT DEFAULT 'buddy', -- 'buddy', 'instructor', 'guide', 'divemaster'
  is_verified BOOLEAN DEFAULT FALSE,
  verified_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_dive_buddies_dive ON dive_buddies(dive_log_id);


-- =============================================
-- TAKİP SİSTEMİ
-- =============================================
CREATE TABLE user_follows (
  follower_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  following_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  created_at TIMESTAMPTZ DEFAULT now(),
  PRIMARY KEY (follower_id, following_id)
);

CREATE INDEX idx_follows_following ON user_follows(following_id);


-- =============================================
-- DALIŞ BEĞENİLERİ
-- =============================================
CREATE TABLE dive_likes (
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  created_at TIMESTAMPTZ DEFAULT now(),
  PRIMARY KEY (dive_log_id, user_id)
);


-- =============================================
-- DALIŞ YORUMLARI (nested)
-- =============================================
CREATE TABLE dive_comments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  comment_text TEXT NOT NULL,
  parent_comment_id UUID REFERENCES dive_comments(id), -- iç içe yorumlar
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now(),
  deleted_at TIMESTAMPTZ
);

CREATE INDEX idx_comments_dive_log ON dive_comments(dive_log_id);


-- =============================================
-- BİLDİRİMLER
-- =============================================
CREATE TABLE notifications (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  type TEXT NOT NULL,
  -- type değerleri:
  -- buddy_request, dive_verified, dive_liked, dive_commented,
  -- follow, equipment_maintenance_due, certification_expiring,
  -- medical_exam_due, tank_inspection_due, achievement_unlocked
  title TEXT NOT NULL,
  body TEXT,
  reference_type TEXT, -- 'dive', 'buddy', 'equipment', 'certification'
  reference_id UUID,
  is_read BOOLEAN DEFAULT FALSE,
  read_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_notifications_user ON notifications(user_id, is_read);


-- =============================================
-- EKİPMAN HATIRLATMALARI
-- =============================================
CREATE TABLE equipment_reminders (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  equipment_id UUID NOT NULL REFERENCES equipment(id) ON DELETE CASCADE,
  reminder_type TEXT NOT NULL, -- 'service_due', 'inspection_due', 'hydro_test_due', 'warranty_expiry'
  reminder_date DATE NOT NULL,
  is_completed BOOLEAN DEFAULT FALSE,
  completed_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_reminders_equipment ON equipment_reminders(equipment_id);


-- =============================================
-- DALIŞ PLANLAMA
-- =============================================
CREATE TABLE dive_plans (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  name TEXT,
  dive_site_id UUID REFERENCES dive_sites(id),
  planned_date DATE,

  -- Planlama parametreleri
  algorithm TEXT, -- 'buhlmann_zhl16c', 'vpm_b'
  gf_low INTEGER,
  gf_high INTEGER,
  conservatism TEXT, -- 'low', 'medium', 'high'

  -- Dalış parametreleri
  max_depth_m NUMERIC(6,2),
  bottom_time_min INTEGER,
  descent_rate NUMERIC(4,1) DEFAULT 18.0, -- m/dk
  ascent_rate NUMERIC(4,1) DEFAULT 9.0,
  last_stop_depth_m NUMERIC(4,1) DEFAULT 3.0,
  altitude_m INTEGER DEFAULT 0,
  breathing_mode TEXT DEFAULT 'open_circuit',
  sac_rate NUMERIC(5,2) DEFAULT 15.0, -- L/min varsayılan

  -- Hesaplanan sonuçlar
  total_runtime_min INTEGER,
  total_deco_min INTEGER,
  total_gas_needed_l NUMERIC(8,1),
  plan_output_text TEXT, -- runtime tablosu

  notes TEXT,
  is_template BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_plans_user_id ON dive_plans(user_id);


-- =============================================
-- DALIŞ PLANI GAZLARI
-- =============================================
CREATE TABLE dive_plan_gases (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_plan_id UUID NOT NULL REFERENCES dive_plans(id) ON DELETE CASCADE,
  gas_order SMALLINT NOT NULL,
  gas_type TEXT NOT NULL, -- 'air', 'nitrox', 'trimix', 'oxygen'
  o2_percent NUMERIC(5,2) NOT NULL,
  he_percent NUMERIC(5,2) DEFAULT 0,
  gas_usage TEXT, -- 'bottom', 'deco', 'travel', 'bailout'
  switch_depth_m NUMERIC(5,1),
  tank_volume_l NUMERIC(5,2),
  start_pressure_bar NUMERIC(5,1),
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_plan_gases_plan ON dive_plan_gases(dive_plan_id);


-- =============================================
-- ÇEVRE KORUMA RAPORU
-- =============================================
CREATE TABLE dive_environmental_reports (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  dive_log_id UUID NOT NULL REFERENCES dive_logs(id) ON DELETE CASCADE,
  reef_health_rating SMALLINT CHECK (reef_health_rating BETWEEN 1 AND 5),
  coral_bleaching_observed BOOLEAN DEFAULT FALSE,
  coral_bleaching_severity TEXT, -- 'none', 'mild', 'moderate', 'severe'
  marine_debris_observed BOOLEAN DEFAULT FALSE,
  debris_types TEXT[], -- ['plastic', 'fishing_line', 'nets', 'cans', 'glass']
  debris_quantity TEXT, -- 'none', 'little', 'moderate', 'lots'
  debris_collected BOOLEAN DEFAULT FALSE,
  debris_collected_kg NUMERIC(5,2),
  invasive_species_observed BOOLEAN DEFAULT FALSE,
  invasive_species_notes TEXT,
  water_quality_notes TEXT,
  general_notes TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_env_reports_dive ON dive_environmental_reports(dive_log_id);


-- =============================================
-- MEDYA ETİKETLERİ
-- =============================================
CREATE TABLE media_tags (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  media_id UUID NOT NULL REFERENCES dive_log_media(id) ON DELETE CASCADE,
  tag_type TEXT, -- 'species', 'equipment', 'buddy', 'location', 'other'
  tag_value TEXT,
  species_id UUID REFERENCES marine_species(id),
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_media_tags_media ON media_tags(media_id);


-- =============================================
-- GÖRÜLEN TÜRLER LİFE LIST (VIEW)
-- =============================================
CREATE VIEW user_species_life_list AS
SELECT
  dl.user_id,
  ms.id AS species_id,
  ms.common_name_tr,
  ms.common_name_en,
  ms.scientific_name,
  ms.category,
  COUNT(dls.id) AS times_seen,
  MIN(dl.dive_date) AS first_seen_date,
  MAX(dl.dive_date) AS last_seen_date
FROM dive_log_species dls
JOIN dive_logs dl ON dls.dive_log_id = dl.id
JOIN marine_species ms ON dls.species_id = ms.id
WHERE dl.deleted_at IS NULL
GROUP BY dl.user_id, ms.id, ms.common_name_tr, ms.common_name_en, ms.scientific_name, ms.category;


-- =============================================
-- RLS POLİCY'LERİ
-- =============================================
-- Ana tablolar
ALTER TABLE dive_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_log_deco_stops ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_log_tanks ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_profile_samples ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_events ENABLE ROW LEVEL SECURITY;

-- Ekipman
ALTER TABLE equipment ENABLE ROW LEVEL SECURITY;
ALTER TABLE equipment_maintenance ENABLE ROW LEVEL SECURITY;
ALTER TABLE equipment_reminders ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_log_equipment ENABLE ROW LEVEL SECURITY;
ALTER TABLE equipment_kits ENABLE ROW LEVEL SECURITY;
ALTER TABLE equipment_kit_items ENABLE ROW LEVEL SECURITY;
ALTER TABLE tanks ENABLE ROW LEVEL SECURITY;

-- Deniz canlıları & çevre
ALTER TABLE dive_log_species ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_environmental_reports ENABLE ROW LEVEL SECURITY;

-- Sertifikalar
ALTER TABLE certifications ENABLE ROW LEVEL SECURITY;

-- Medya
ALTER TABLE dive_log_media ENABLE ROW LEVEL SECURITY;
ALTER TABLE media_tags ENABLE ROW LEVEL SECURITY;

-- Sosyal
ALTER TABLE buddies ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_buddies ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_follows ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_likes ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_comments ENABLE ROW LEVEL SECURITY;

-- Başarımlar & bildirimler
ALTER TABLE user_achievements ENABLE ROW LEVEL SECURITY;
ALTER TABLE notifications ENABLE ROW LEVEL SECURITY;

-- Kişisel bilgiler
ALTER TABLE emergency_info ENABLE ROW LEVEL SECURITY;
ALTER TABLE trips ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_invitations ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_plans ENABLE ROW LEVEL SECURITY;
ALTER TABLE dive_plan_gases ENABLE ROW LEVEL SECURITY;

-- Örnek RLS policy'leri (dive_logs)

-- Sahip her zaman kendi dalışlarını görür
CREATE POLICY "Kullanıcı kendi loglarını görebilir"
  ON dive_logs FOR SELECT
  USING (auth.uid() = user_id);

-- Public dalışları herkes görür
CREATE POLICY "Public logları herkes görebilir"
  ON dive_logs FOR SELECT
  USING (visibility = 'public' AND deleted_at IS NULL);

-- Friends dalışlarını sadece takipçiler görür
CREATE POLICY "Friends loglarını takipçiler görebilir"
  ON dive_logs FOR SELECT
  USING (
    visibility = 'friends'
    AND deleted_at IS NULL
    AND EXISTS (
      SELECT 1 FROM user_follows
      WHERE follower_id = auth.uid()
        AND following_id = dive_logs.user_id
    )
  );

CREATE POLICY "Kullanıcı kendi loglarını oluşturabilir"
  ON dive_logs FOR INSERT
  WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Kullanıcı kendi loglarını düzenleyebilir"
  ON dive_logs FOR UPDATE
  USING (auth.uid() = user_id);

CREATE POLICY "Kullanıcı kendi loglarını silebilir"
  ON dive_logs FOR DELETE
  USING (auth.uid() = user_id);

4.2 Tablo İlişki Diyagramı (Özet)

auth.users (Supabase)
  ├── dive_logs (1:N) — Ana dalış kaydı
  │     ├── dive_log_deco_stops (1:N)
  │     ├── dive_log_tanks (1:N)
  │     ├── dive_profile_samples (1:N) — zaman serisi veri noktaları
  │     ├── dive_events (1:N) — dalış olayları (gaz değişimi, alarm vb.)
  │     ├── dive_log_equipment (N:M → equipment)
  │     ├── dive_log_species (1:N → marine_species)
  │     ├── dive_log_media (1:N)
  │     │     └── media_tags (1:N → marine_species)
  │     ├── dive_buddies (1:N → buddies / profiles)
  │     ├── dive_environmental_reports (1:1)
  │     ├── dive_likes (1:N)
  │     ├── dive_comments (1:N, self-ref nested)
  │     └── user_achievements (N:M → achievements)
  ├── trips (1:N) — seyahat gruplaması
  │     └── dive_logs (FK)
  ├── equipment (1:N)
  │     ├── equipment_maintenance (1:N)
  │     ├── equipment_reminders (1:N)
  │     └── equipment_kit_items (N:M → equipment_kits)
  ├── equipment_kits (1:N)
  ├── tanks (1:N) — tüp yönetimi (hydro test, visual inspection)
  ├── buddies (1:N) — kayıtsız buddy rehberi
  ├── certifications (1:N)
  ├── emergency_info (1:1)
  ├── notifications (1:N)
  ├── dive_invitations (1:N — inviter/invitee)
  ├── dive_plans (1:N)
  │     └── dive_plan_gases (1:N)
  └── user_follows (N:M — follower/following)

dive_sites (mevcut tablo)
  ├── dive_logs (FK)
  └── dive_plans (FK)

dive_schools (mevcut tablo)
  └── dive_logs (FK)

certification_agencies (referans)
  └── certification_levels (1:N)

marine_species (referans)
  ├── dive_log_species (FK)
  └── media_tags (FK)

hyperbaric_chambers (bağımsız, PostGIS)

achievements (referans)
  └── user_achievements (FK)

-- VIEW
user_species_life_list → dive_log_species + dive_logs + marine_species

4.3 Toplam Tablo/View Sayısı

KategoriTablo Sayısı
Dalış kaydı (ana + alt tablolar)7
Ekipman & tüp6
Sertifika3
Deniz canlıları & çevre3
Medya2
Sosyal & buddy5
Başarımlar & bildirimler4
Kişisel bilgiler & planlama5
Referans3
View1
Toplam39

5. Rakiplerden Farklılaşma Stratejisi

ÖzellikTurkeyScuba Avantajı
TSSF/CMAS entegrasyonuHiçbir platformda yok — Türkiye dalış pazarında tek
Dalış merkezi + dalgıç birleşik platformB2B+B2C model — merkez ve dalgıç aynı ekosistemde
Mevcut dalış noktaları DBZaten 100+ Türkiye dalış noktası var, logbook'la entegre
Hava hesaplama aracı entegreDECO 2000 zaten var, plan → log dönüşümü yapılabilir
Offline-firstSu altı = internet yok. Rakiplerin çoğu bulut bağımlı
Modern UISubsurface/Diviac/divelogs.de hepsi eski — tasarım avantajı
Abonelik yokTemel logbook ücretsiz — Deepblu'nun hatasını tekrarlama
Çoklu kuruluş sertifikaPADI + SSI + CMAS/TSSF + diğerleri tek yerde
Çevre verisi otomatik doldurmaSadece Wikibubbles'da var (çok yeni, küçük)
Biyoçeşitlilik katkısıSadece Diveboard'da var — bilimsel değer

6. Öncelik Sıralaması (Fazlar)

Faz A — MVP Logbook

  1. dive_logs tablosu + CRUD (temel alanlar)
  2. trips tablosu (seyahat gruplaması)
  3. Manuel dalış girişi formu (wizard — adım adım)
  4. Dalış listesi (tarih sıralı, trip bazlı gruplama)
  5. Dalış detay sayfası (profil grafiği, koşullar, notlar)
  6. Temel istatistikler (toplam dalış, maks derinlik, toplam süre)
  7. Dalış noktası ilişkilendirme (mevcut DB)
  8. tanks tablosu + tüp yönetimi

Faz B — Zenginleştirme

  1. Ekipman yönetimi + bakım takibi + hatırlatıcılar
  2. Sertifika takibi (çoklu kuruluş — certification_agencies + certification_levels)
  3. Buddy sistemi (buddies + dive_buddies) + QR doğrulama
  4. Fotoğraf/video ekleme (R2) + media_tags
  5. Derinlik profili görselleştirme (SVG — dive_profile_samples verisinden)
  6. UDDF/CSV import + dosya hash kontrolü (duplikasyon önleme)
  7. dive_events tablosu (gaz değişimi, alarm, bookmark)

Faz C — Sosyal & Topluluk

  1. Takip sistemi (user_follows)
  2. Dalış beğenme (dive_likes) + yorumlar (dive_comments — nested)
  3. Feed/akış (takip edilen kişilerin dalışları)
  4. 3 seviye gizlilik (public / friends / private)
  5. Bildirim sistemi (notifications)
  6. Dalış daveti (dive_invitations)

Faz D — Akıllı Özellikler

  1. Otomatik çevre verisi doldurma (OpenMeteo/StormGlass API)
  2. Gamifikasyon (rozetler/başarımlar)
  3. SAC rate trendi ve analiz dashboard
  4. Acil durum bilgileri + basınç odası bulucu (PostGIS)
  5. Deniz canlıları loglama + user_species_life_list VIEW
  6. Çevre koruma raporu (dive_environmental_reports)

Faz E — İleri Özellikler

  1. AI tür tanımlama (fotoğraftan otomatik tür teşhisi)
  2. Dalış planlama (dive_plans + dive_plan_gases) → log dönüşümü
  3. Eğitmen/merkez paneli entegrasyonu (beceri değerlendirme, debrief)
  4. Offline-first (PWA + IndexedDB/SQLite WASM)
  5. Çoklu bilgisayar import (FIT, SML, Shearwater XML, Mares MDB)
  6. Biyoçeşitlilik veri katkısı (GBIF/OBIS)
  7. Akıllı dalış önerisi (hava/gelgit/görüş/deneyim)
  8. 3D dalış profili görselleştirme (GPS + derinlik)
  9. Anomali tespiti ve güvenlik uyarıları
  10. Export: PDF, Excel, KML/KMZ, GPX, HTML