# MongoDB Veritabanı Yapısı ve Koleksiyonları

**Son Güncelleme:** 2025-01-06

## 📋 Genel Bakış

FikoYT sisteminde MongoDB veritabanı, tüm uygulamalar (Go backend, Angular, Flutter) için merkezi veri deposu görevi görür. Sistem, dinamik koleksiyon yönetimi, FikoYTMap tip sistemi ve GridFS entegrasyonu ile modern bir veri yönetimi mimarisi sunar.

## 🗄️ Veritabanı Yapısı

### Ana Veritabanı: `fikoyt`

- **Port:** 27017
- **Connection URI:** Environment variable `mongo_uri` üzerinden yönetilir
- **Session Storage:** `go_sessions` koleksiyonunda saklanır

---

## 📚 Koleksiyonlar ve Schemalar

### 1. Sistem Koleksiyonları

#### `go_sessions`
**Amaç:** Kullanıcı oturum bilgilerinin saklanması
```typescript
interface SessionDocument {
  _id: string;          // Session ID
  sid: string;          // Session identifier
  data: any;            // JSON serialized session data
  expires?: Date;       // Session expiration time
}
```

#### `goUyeler`
**Amaç:** Sistem kullanıcıları ve üyeler
```typescript
interface UyeDocument {
  _id: ObjectId;
  kullaniciAdi: string;
  eposta: string;
  sifre: string;        // Hash'li
  rol: string;          // admin, user, etc.
  aktif: boolean;
  olusturmaTarihi: Date;
  sonGirisTarihi?: Date;
  profil?: {
    isim: string;
    soyisim: string;
    avatar?: string;
  };
}
```

#### `goSoketler`
**Amaç:** Socket.io bağlantı yönetimi
```typescript
interface SocketDocument {
  _id: ObjectId;
  socketId: string;
  userId?: ObjectId;
  cihazId?: string;
  baglantiZamani: Date;
  sonAktivite: Date;
  durum: 'aktif' | 'pasif' | 'baglantikoptu';
  metadata?: any;
}
```

#### `goCihazlar`
**Amaç:** Cihaz kayıt ve yönetimi
```typescript
interface CihazDocument {
  _id: ObjectId;
  cihazKimlik: string;
  ismi: string;
  tip: 'web' | 'mobil' | 'desktop';
  sistemBilgiler: any;
  userId?: ObjectId;
  kayitZamani: Date;
  sonGiris: Date;
  aktif: boolean;
}
```

### 2. İş Koleksiyonları

#### `goFirmalar`
**Amaç:** Firma yönetim sistemi
```typescript
interface FirmaDocument {
  _id: ObjectId;
  isim: string;                    // Firma adı (zorunlu)
  unvan?: string;                  // Ünvan
  vergiNo?: string;                // Vergi numarası
  vergiDairesi?: string;           // Vergi dairesi

  // Adres bilgileri - çoklu destek
  adres?: IFirmaAdres;             // Geriye uyumluluk
  adresler?: IFirmaAdres[];        // Yeni çoklu adres

  // İletişim bilgileri - çoklu destek
  iletisim?: IFirmaIletisim;       // Geriye uyumluluk
  iletisimler?: IFirmaIletisim[];  // Yeni çoklu iletişim

  // Yetkili kişiler - çoklu destek
  yetkiliKisi?: IYetkiliKisi;      // Geriye uyumluluk
  yetkiliKisiler?: IYetkiliKisi[]; // Yeni çoklu yetkili

  // Logo yönetimi
  logoUrl?: string;                // Eski URL formatı
  logoId?: ObjectId;               // GridFS dosya ID

  // Paylaşım ve yetkilendirme
  olusturanKullanici: ObjectId;
  paylasilanKullanicilar: ObjectId[];

  // Durum ve zamanlama
  aktif: boolean = true;
  olusturmaTarihi: Date;
  guncellemeTarihi: Date;

  // Esnek alanlar
  ekBilgiler?: { [key: string]: any };
}

interface IFirmaAdres {
  id?: string;                     // Benzersiz ID
  etiket?: string;                 // "Merkez", "Şube", "Depo"
  il?: string;
  ilce?: string;
  mahalle?: string;
  cadde?: string;
  binaNo?: string;
  daireNo?: string;
  postaKodu?: string;
  ulke?: string;
  acikAdres?: string;
  varsayilan?: boolean = false;    // Varsayılan adres
}

interface IFirmaIletisim {
  id?: string;                     // Benzersiz ID
  etiket?: string;                 // "Merkez", "Muhasebe"
  telefon?: string;
  gsm?: string;
  faks?: string;
  eposta?: string;
  webSitesi?: string;
  varsayilan?: boolean = false;    // Varsayılan iletişim
}

interface IYetkiliKisi {
  id?: string;                     // Benzersiz ID
  etiket?: string;                 // "Genel Müdür", "Satış Müdürü"
  isim?: string;
  soyIsim?: string;
  unvan?: string;
  telefon?: string;
  eposta?: string;
  departman?: string;
  varsayilan?: boolean = false;    // Varsayılan yetkili
}
```

#### `hareketler`
**Amaç:** Finansal hareketler ve işlemler
```typescript
interface HareketDocument {
  _id: ObjectId;
  tur: 'gelir' | 'gider' | 'transfer';
  kategori: string;
  aciklama: string;
  tutar: number;
  paraBirimi: string = 'TRY';
  tarih: Date;
  firmaId?: ObjectId;
  projeId?: ObjectId;
  kullaniciId: ObjectId;
  belgeNo?: string;
  dosyalar?: ObjectId[];           // GridFS dosya ID'leri
  etiketler?: string[];
  durum: 'taslak' | 'onaybekliyor' | 'onaylandi' | 'iptal';
  olusturmaTarihi: Date;
  guncellemeTarihi: Date;
}
```

#### `projeler`
**Amaç:** Proje yönetimi
```typescript
interface ProjeDocument {
  _id: ObjectId;
  projeAdi: string;
  aciklama?: string;
  durum: 'planlama' | 'devam' | 'tamamlandi' | 'iptal';
  baslangicTarihi: Date;
  bitisTarihi?: Date;
  mudurId: ObjectId;
  calisanlar: ObjectId[];
  musteriId?: ObjectId;
  butce?: number;
  gerceklesen?: number;
  etiketler?: string[];
  dosyalar?: ObjectId[];
  olusturanKullanici: ObjectId;
  olusturmaTarihi: Date;
  guncellemeTarihi: Date;
}
```

#### `stoklar`
**Amaç:** Stok ve envanter yönetimi
```typescript
interface StokDocument {
  _id: ObjectId;
  stokKodu: string;
  urunAdi: string;
  aciklama?: string;
  kategori: string;
  birim: string;                   // adet, kg, litre, etc.
  miktar: number;
  minStokSeviyesi: number;
  maxStokSeviyesi?: number;
  birimFiyat: number;
  toplamDeger: number;
  depo?: string;
  raf?: string;
  tedarikciId?: ObjectId;
  barkod?: string;
  resimId?: ObjectId;              // GridFS ürün resmi
  aktif: boolean = true;
  olusturanKullanici: ObjectId;
  olusturmaTarihi: Date;
  guncellemeTarihi: Date;
}
```

#### `teklifler`
**Amaç:** Teklif yönetimi
```typescript
interface TeklifDocument {
  _id: ObjectId;
  teklifNo: string;
  firmaId: ObjectId;
  projeId?: ObjectId;
  gecerlilikTarihi: Date;
  toplamTutar: number;
  paraBirimi: string = 'TRY';
  durum: 'taslak' | 'gonderildi' | 'kabul' | 'red' | 'suresidoldu';
  icerik: TeklifKalem[];
  notlar?: string;
  vergiler?: {
    kdv: number;
    digerVergiler?: number[];
  };
  dosyalar?: ObjectId[];
  olusturanKullanici: ObjectId;
  olusturmaTarihi: Date;
  guncellemeTarihi: Date;
}

interface TeklifKalem {
  urunAdi: string;
  aciklama?: string;
  miktar: number;
  birimFiyat: number;
  toplam: number;
  birim: string;
}
```

### 3. Dosya Yönetimi (GridFS)

#### `go_files.files` ve `go_files.chunks`
**Amaç:** Tüm dosya tiplerinin saklanması (logolar, belgeler, resimler)

```typescript
interface GridFSFileDocument {
  _id: ObjectId;
  filename: string;
  contentType: string;
  length: number;
  uploadDate: Date;
  aliases?: string[];
  metadata: {
    koleksiyon: string;            // Hangi koleksiyona ait
    kid: ObjectId?;                // Kullanıcı ID
    yol: string;                   // Dosya yolu
    thumb_id?: ObjectId;           // Thumbnail ID
    parent_file_id?: ObjectId;     // Ana dosya ID
    parent_collection?: string;    // Ana koleksiyon
    dosya?: {
      adi: string;
      boyut: number;
      uzanti: string;
    };
    [key: string]: any;            // Ek metadata
  };
  chunkSize: number;
  md5: string;
}
```

### 4. Dinamik Koleksiyonlar

Sistem, herhangi bir koleksiyon adı ile dinamik olarak çalışabilir:
- `kullanicilar`
- `logolar`
- `dokumanlar`
- `urunler`
- `siparisler`
- vs...

---

## 🔧 FikoYTMap Tip Sistemi

### Tanım
FikoYTMap, Go backend'te veri manipülasyonu için özel bir tip systemidir:

```go
type FikoYTMap fiber.Map
```

### Özellikler

#### 1. ObjectId Dönüşümü
```go
func (f FikoYTMap) IsleObjectId() FikoYTMap
```
- 24 karakterli string'leri otomatik ObjectId'ye çevirir
- Recursive olarak nested objeleri dönüştürür
- Array'lerdeki elemanları dönüştürür

#### 2. Alan Validasyonu
```go
func (f FikoYTMap) BosAlanlar() []string
func (f FikoYTMap) TumAlanlarDolumu() bool
```
- Null, empty string ve false değerlerini kontrol eder
- Zorunlu alan validasyonu için kullanılır

#### 3. BSON Dönüşümü
```go
func (f FikoYTMap) ToBsonM() bson.M
```
- MongoDB operasyonları için BSON formatına çevirir

---

## 🔄 Aggregation Pipelines ve Karmaşık Sorgular

### Örnek Aggregation Sorguları

#### 1. Firma İstatistikleri
```typescript
const aggregate = [
  {
    $match: { aktif: true }
  },
  {
    $group: {
      _id: null,
      toplamFirma: { $sum: 1 },
      aktifFirma: {
        $sum: { $cond: [{ $eq: ["$aktif", true] }, 1, 0] }
      }
    }
  },
  {
    $project: {
      _id: 0,
      toplamFirma: 1,
      aktifFirma: 1,
      pasifFirma: { $subtract: ["$toplamFirma", "$aktifFirma"] }
    }
  }
];
```

#### 2. Aylık Finansal Rapor
```typescript
const aggregate = [
  {
    $match: {
      tarih: {
        $gte: new Date(baslangicTarihi),
        $lte: new Date(bitisTarihi)
      }
    }
  },
  {
    $group: {
      _id: {
        yil: { $year: "$tarih" },
        ay: { $month: "$tarih" },
        tur: "$tur"
      },
      toplamTutar: { $sum: "$tutar" },
      islemSayisi: { $sum: 1 }
    }
  },
  {
    $sort: { "_id.yil": -1, "_id.ay": -1 }
  }
];
```

#### 3. Proje Performans Analizi
```typescript
const aggregate = [
  {
    $lookup: {
      from: "hareketler",
      localField: "_id",
      foreignField: "projeId",
      as: "hareketler"
    }
  },
  {
    $addFields: {
      gerceklesenMaliyet: {
        $sum: "$hareketler.tutar"
      },
      bakiye: {
        $subtract: ["$butce", { $sum: "$hareketler.tutar" }]
      }
    }
  },
  {
    $project: {
      projeAdi: 1,
      durum: 1,
      butce: 1,
      gerceklesenMaliyet: 1,
      bakiye: 1,
      performansYuzdesi: {
        $cond: [
          { $eq: ["$butce", 0] },
          0,
          { $multiply: [{ $divide: ["$gerceklesenMaliyet", "$butce"] }, 100] }
        ]
      }
    }
  }
];
```

---

## 🚀 Performans Optimizasyonları ve Indexler

### Önerilen Indexler

#### 1. Firma Koleksiyonu Index'leri
```javascript
// Temel arama index'leri
db.goFirmalar.createIndex({ "isim": "text", "unvan": "text" })
db.goFirmalar.createIndex({ "olusturanKullanici": 1 })
db.goFirmalar.createIndex({ "aktif": 1 })
db.goFirmalar.createIndex({ "vergiNo": 1 }, { unique: true, sparse: true })

// Çoklu değerli alanlar için
db.goFirmalar.createIndex({ "adresler.il": 1 })
db.goFirmalar.createIndex({ "iletisimler.eposta": 1 })
db.goFirmalar.createIndex({ "yetkiliKisiler.eposta": 1 })
```

#### 2. Hareketler Koleksiyonu Index'leri
```javascript
db.hareketler.createIndex({ "tarih": -1 })
db.hareketler.createIndex({ "kullaniciId": 1, "tarih": -1 })
db.hareketler.createIndex({ "firmaId": 1, "tarih": -1 })
db.hareketler.createIndex({ "tur": 1, "tarih": -1 })
db.hareketler.createIndex({ "durum": 1 })
db.hareketler.createIndex({ "etiketler": 1 })
```

#### 3. Proje Koleksiyonu Index'leri
```javascript
db.projeler.createIndex({ "mudurId": 1 })
db.projeler.createIndex({ "calisanlar": 1 })
db.projeler.createIndex({ "durum": 1 })
db.projeler.createIndex({ "baslangicTarihi": -1 })
db.projeler.createIndex({ "musteriId": 1 })
```

#### 4. Socket ve Cihaz Index'leri
```javascript
db.goSoketler.createIndex({ "socketId": 1 }, { unique: true })
db.goSoketler.createIndex({ "userId": 1 })
db.goSoketler.createIndex({ "durum": 1, "sonAktivite": -1 })

db.goCihazlar.createIndex({ "cihazKimlik": 1 }, { unique: true })
db.goCihazlar.createIndex({ "userId": 1 })
db.goCihazlar.createIndex({ "aktif": 1, "sonGiris": -1 })
```

### Performans İpuçları

#### 1. Aggregation Optimizasyonu
- Early filtering: `$match` stage'leri pipeline başında kullanın
- Projection: Sadece gerekli alanları getirin
- Index utilization: Index'li alanlara göre `$match` ve `$sort` yapın
- Memory usage: Büyük dataset'lerde `allowDiskUse` kullanın

#### 2. GridFS Optimizasyonu
- Chunk size: Büyük dosyalar için 255KB yerine 1MB kullanın
- Metadata: Minimal metadata tutun
- Compression: Sunucu tarafında compression kullanın

#### 3. Connection Pool
- Max connections: 100-200 arası
- Min connections: 10-20 arası
- Connection timeout: 30 saniye

---

## 🔄 Veri Akış Pattern'leri

### 1. CRUD Operasyonları

#### Create (Ekleme)
```typescript
// Angular/Flutter -> Go Backend -> MongoDB
POST /fapiv1/uyar-dokum/goFirmalar
{
  "isim": "Test Firma",
  "vergiNo": "1234567890",
  // ... diğer alanlar
}
```

#### Read (Okuma)
```typescript
// Direct aggregation
POST /fapiv1/uyar-dokum/goFirmalar/aggregate
{
  "aggregate": [
    { $match: { aktif: true } },
    { $limit: 50 }
  ]
}
```

#### Update (Güncelleme)
```typescript
POST /fapiv1/uyar-dokum/goFirmalar/guncelle
{
  "filter": { "_id": "..." },
  "veri": { "isim": "Yeni Firma Adı" },
  "upsert": false,
  "multi": false
}
```

#### Delete (Silme)
```typescript
POST /fapiv1/uyar-dokum/goFirmalar/sil
{
  "_id": "..."
}
```

### 2. Dosya Yükleme Pattern'i

```typescript
// 1. Dosya yükleme isteği
POST /fapiv1/uyar-dokum/dosya-yukle/goFirmalar
Content-Type: multipart/form-data

// 2. Arka plan işlemi
- Dosya geçici olarak kaydedilir
- Thumbnail oluşturulur
- GridFS'e kaydedilir
- Ana dokümana file_id eklenir

// 3. Durum sorgulama
GET /fapiv1/uyar-dokum/dosya-bilgi/{fileId}
```

### 3. Real-time Veri Akışı

```typescript
// Socket.io event pattern'i
socket.on('FikoYT.sistem.cihaz.bağlandı.toplamlar', (data) => {
  // Cihaz bağlantı verileri
});

socket.on('hareket-degisti', (data) => {
  // Finansal hareket güncellemeleri
});
```

---

## 🔒 Veri Validasyonu ve Constraints

### 1. Schema Validation
```javascript
// Firma koleksiyonu için validator
db.runCommand({
  collMod: "goFirmalar",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["isim", "olusturanKullanici", "aktif"],
      properties: {
        isim: {
          bsonType: "string",
          minLength: 1,
          maxLength: 200
        },
        vergiNo: {
          bsonType: "string",
          pattern: "^[0-9]{10}$"
        },
        aktif: {
          bsonType: "bool"
        }
      }
    }
  }
});
```

### 2. Unique Constraints
```javascript
// Vergi numarası unique constraint
db.goFirmalar.createIndex(
  { vergiNo: 1 },
  {
    unique: true,
    partialFilterExpression: { vergiNo: { $exists: true, $ne: null } }
  }
);
```

### 3. Referential Integrity
```javascript
// Application level referential integrity
// Örnek: Firma silinmeden önce hareket kontrolü
const firmaHareketSayisi = await db.hareketler.countDocuments({
  firmaId: firmaId
});

if (firmaHareketSayisi > 0) {
  throw new Error('Firmaya ait hareketler bulunmaktadır. Silinemez.');
}
```

---

## 📱 Uygulama Spesifik Veri Modelleri

### Angular (TypeScript) Interface'leri
```typescript
// src/app/uygulamalar/uyar-dokum/firmalar/firmalar.service.ts
export interface IFirma {
  _id?: string | any;
  isim: string;
  unvan?: string;
  // ... diğer alanlar
}
```

### Flutter (Dart) Modelleri
```dart
// flutter/fikoyt_akcali/lib/apps/finans/model/model_hareketler.dart
@Collection()
class Hareketler {
  Id id = Isar.autoIncrement;

  @Index()
  late String tur;

  late double tutar;
  late DateTime tarih;

  // ... diğer alanlar
}
```

### Go (Backend) Struct'ları
```go
// Backend'te FikoYTMap kullanılır
type FikoYTMap fiber.Map

// ObjectId conversion handled automatically
func (f FikoYTMap) IsleObjectId() FikoYTMap
```

---

## 🔄 Migration ve Versiyonlama

### 1. Database Versioning
```typescript
// version collection
interface VersionDocument {
  _id: ObjectId;
  version: string;
  description: string;
  appliedAt: Date;
  migrationName: string;
}
```

### 2. Migration Pattern'leri
```javascript
// Backward compatible field additions
// Yeni alanlar optional olmalı
db.goFirmalar.updateMany(
  {},
  {
    $set: {
      "yeniAlan": "varsayilanDeger"
    }
  }
);

// Data transformation for schema changes
db.goFirmalar.aggregate([
  {
    $project: {
      isim: 1,
      // eski alandan yeni alana dönüşüm
      yeniAlan: { $ifNull: ["$eskiAlan", "varsayilan"] }
    }
  },
  {
    $out: "goFirmalar_temp"
  }
]);
```

---

## 🔍 Monitoring ve Debugging

### 1. Slow Query Monitoring
```javascript
// Slow queries'yu logla
db.setProfilingLevel(2, { slowms: 100 });

// Profil verilerini incele
db.system.profile.find().sort({ ts: -1 }).limit(5);
```

### 2. Index Usage Analysis
```javascript
// Index kullanım istatistikleri
db.goFirmalar.aggregate([{ $indexStats: {} }]);

// Query execution plan
db.goFirmalar.find({ isim: "Test" }).explain("executionStats");
```

### 3. Connection Monitoring
```go
// Go backend connection pool monitoring
if err := Client.Ping(context.TODO(), nil); err != nil {
    log.Printf("MongoDB bağlantı hatası: %v", err)
}
```

---

## 🛡️ Backup ve Recovery

### 1. Backup Strategy
```bash
# Full backup
mongodump --uri="mongodb://username:password@host:27017/fikoyt" --out=/backup/$(date +%Y%m%d)

# GridFS backup
mongofiles --uri="mongodb://username:password@host:27017/fikoyt" list
mongofiles --uri="mongodb://username:password@host:27017/fikoyt" get "filename"
```

### 2. Point-in-Time Recovery
```bash
# Oplog kullanarak recovery
mongorestore --uri="mongodb://username:password@host:27017/fikoyt" --oplogReplay /backup/20250106
```

---

## 📊 İstatistikler ve Metrikler

### 1. Collection Statistics
```javascript
// Koleksiyon büyüklükleri
db.runCommand({ collStats: "goFirmalar" });
db.runCommand({ collStats: "hareketler" });

// Veritabanı genel istatistikler
db.stats();
```

### 2. Performance Metrics
```javascript
// Server status
db.serverStatus();

// Current operations
db.currentOp();
```

---

## 🚨 Best Practices

### 1. Query Optimization
- **Always use indexes** for query fields
- **Limit result sets** with pagination
- **Use projections** to return only needed fields
- **Avoid $where** for performance reasons

### 2. Data Modeling
- **Embed related data** for read performance
- **Reference data** for write performance and consistency
- **Use arrays** sparingly and index them properly
- **Consider document size limits** (16MB)

### 3. Security
- **Use authentication** and authorization
- **Enable encryption** for sensitive data
- **Use role-based access control**
- **Regular security audits**

### 4. Scalability
- **Shard large collections** when needed
- **Use read replicas** for read-heavy workloads
- **Monitor performance metrics** regularly
- **Plan capacity** based on growth patterns

---

## 🔗 İlişkili Dokümanlar

- [Three.js Sistemi](./02-threejs-sistemi.md)
- [Dialog Sistemi](./03-dialog-sistemi.md)
- [FreeCAD Entegrasyonu](./04-freecad-entegrasyonu.md)
- [Socket.io İletişim](./05-socketio-iletisim.md)
- [State Management](./06-state-management.md)
- [Kritik Dosyalar](./07-kritik-dosyalar.md)
- [Best Practices](./08-best-practices.md)

---

**Not:** Bu doküman sistemdeki mevcut koleksiyonları, veri akışını ve MongoDB optimizasyonlarını kapsamlı şekilde açıklamaktadır. Yeni koleksiyonlar eklendiğinde veya mevcut schemalar güncellendiğinde bu dokümanın güncellenmesi gerekir.