AI ile 20 Saatte Komple Mail Sunucusu Geliştirdim — İşte Gerçekte Olan
Özet
- Meydan Okuma: Tek bir günde Mailcow alternatifi, tam fonksiyonel, modern bir mail sunucusu inşa etmek.
- Teknoloji Yığını: Vue 3, NestJS, Vite, Go (TUI), Docker, Postfix, Dovecot.
- Sonuç: Sıfırdan üretime hazır monorepo’ya 20 saatte geçiş.
- Kahraman: Sıkı bir kural: “Eğer E2E testleri geçmezse, ilerlemeyiz. Özellik tamamlanmamış sayılır.”
- ROI (Yatırım Getirisi): 400 saatlik geleneksel geliştirme süreci 20 saate indi (~%95 tasarruf).
Bu belge teknik bir rapor değil; modern yazılım geliştirme klişeleri, Docker ağları ve “gereksiz karmaşıklık” ile boğuşan bir insan ve bir yapay zekanın (GitHub Copilot) hikayesidir.
Bu hikayenin gizli kahramanı katı bir kuraldı: “Eğer E2E testleri geçmezse, özellik yok demektir.” Bu, mevcut görev tamamen doğrulanana kadar asla bir sonraki göreve geçmediğimiz anlamına geliyordu.
1. Vizyon: “Mailcow ama Modern”
Gün sabah 08:00’de başladı. Kahve elde, terminal açık.
Hedef iddialı ama “netti”: Mailcow veya Mailu’ya modern bir alternatif olarak hizmet veren tam fonksiyonel bir mail sunucusu inşa etmek. Şöyle olmalıydı:
- Modern: Vue 3, NestJS, Vite.
- Basit: Gereksiz kuyruklar (queue) yok, ağır Java bileşenleri yok.
- Dağıtılabilir: Kurulum için tek bir binary, çalıştırmak için tek bir docker-compose.
Temeli Postfix ve Dovecot konfigürasyonlarıyla (configs/main.cf) atarak başladım. Sonra, ilk pivot gerçekleşti. Yapay zeka, yükleyici (installer) için devasa bir Node.js mimarisi önerdi. Reddettim. Sonuç: TUI (Terminal Arayüzü) tabanlı bir yükleyici için Go diline pivot ettik. Saat 10:00’a gelindiğinde, Linux ARM64 üzerinde çalışan pürüzsüz bir kurulum betiğimiz vardı.
2. Protokol: Yapay Zeka ile Nasıl Konuşulur?
Bu projenin bu kadar hızlı başlamasını sağlayan şey sadece kodlama hızı değil, kurduğumuz sıkı iletişim protokolüydü. Kodu sadece “istemedik”; onunla “pazarlık ettik”.
3. Kodlama Maratonu: Çekirdeği İnşa Etmek
10:00 ile 14:00 arasında “akışa” (zone) girdik.
Yönetim Paneli (NestJS + Vue3)
Backend ve frontend’i eş zamanlı inşa ettik. Yapay zeka NestJS’teki DTO’ları ve Controller’ları üretirken, ben Vue Bileşenlerini rafine ettim.
Webmail İstemcisi (Vite + Vue3)
Bu daha zorluydu. Masaüstü uygulaması gibi hissettiren bir arayüze ihtiyacımız vardı. Hız için Vite kullandık.
”Basitleştirme” (Redis’in Kaldırılması)
Akşama doğru, docker-compose logları akarken davetsiz bir misafir gördüm: redis_1.
Ben: “Redis nereden çıktı? Postgres’imiz var. Belleğimiz (Memory) var. Basit tut. Sök at onu.”
Refactor Döngüsü:
- Redis’i Docker Compose’dan sil.
- Redis modülünü NestJS’ten sök.
- Sonuç: Sistem hala çalışıyor. Karmaşıklık azaldı.
4. Güvenlik Ağı: Birim Testleri
E2E savaşına dalmadan önce, pazarlık edilemez bir temel oluşturduk: %100 Birim Test Kapsamı.
E2E testleri kullanıcının mutlu olmasını sağlarken, Birim Testleri geliştiricinin geceleri rahat uyumasını sağladı.
Temel Başarılar:
- Servis İzolasyonu: Her servis (IMAP, SMTP, Auth) izole bir şekilde mock’landı ve test edildi.
- Uç Durumlar (Edge Cases): Ya IMAP bağlantısı koparsa? Ya disk dolarsa? Bu “imkansız” senaryolar için testler yazdık.
- Sıkı Ayrıştırma (Parsing):
parseIntin tehlikeli olduğunu gördük, bu yüzden her şeyi birim testlerle doğrulanmış daha sıkı sayı ayrıştırıcılarına (number parsers) refactor ettik.
Kapsama raporu sadece bir metrik değildi; bizim “Bitti” tanımımızdı.
5. Gerçek Savaş: E2E Testleri
Bu, 20 saatlik maratonun en kritik kısmıydı (14:00 - 22:00). Burada hiçbir şeyi mock’lamadık. Gerçek Docker konteynerleri, gerçek Postfix, gerçek veritabanları.
Bölüm A: Yönetim Paneli & Giriş Kontrol Listesi
Yönetim Paneli testleri bizim için asıl sınav yeriydi. Kimlik Doğrulama gibi kritik özellikler için sıkı bir kontrol listesi tanımladık.
| Test Durumu | Açıklama | Durum |
|---|---|---|
| TC-LOGIN-010 | Boş email ile gönder - hata göster | ✅ |
| TC-LOGIN-011 | Boş şifre ile gönder - hata göster | ✅ |
| TC-LOGIN-012 | Geçersiz email formatı (@ eksik) | ✅ |
| TC-LOGIN-020 | Geçersiz bilgilerle giriş - hata göster | ✅ |
| TC-LOGIN-021 | Başarılı giriş dashboard’a yönlendirir | ✅ |
| TC-LOGIN-030 | Dashboard’a oturum açmadan erişim -> yönlendir | ✅ |
Bölüm B: Webmail & Oluşturma (Compose) Kontrol Listesi
Webmail ağ izolasyonu yüzünden daha zordu (Docker ağları acımasızdır). Ama bir kez bağlandığında, her kullanıcı etkileşimini doğruladık.
| Test Durumu | Açıklama | Durum |
|---|---|---|
| TC-COMPOSE-010 | ’Kime’ (To) girişi görünürlüğü | ✅ |
| TC-COMPOSE-015 | Editör görünürlüğü | ✅ |
| TC-COMPOSE-021 | Kalın (Bold) butonu görünürlüğü | ✅ |
| TC-COMPOSE-026 | Dosya ekle butonu görünürlüğü | ✅ |
| TC-COMPOSE-030 | Gönder butonu görünürlüğü | ✅ |
| TC-COMPOSE-040 | Alıcı olmadan gönder -> Hata Göster | ✅ |
| TC-COMPOSE-045 | İptal geri yönlendirir | ✅ |
| TC-COMPOSE-050 | Dosya girişi varlık kontrolü | ✅ |
Bölüm C: E2E Tarafından Bulunan “Gizli” Hatalar
Testler sadece kodu doğrulamadı; insanların gözden kaçırdığı hataları buldu.
- Vue Render Çökmesi: Kenar çubuğunu (sidebar) açıp kapatmak için özel bir test,
folders.findın bir Dizi (Array) yerine bir Obje (Object) üzerinde çağrılması nedeniyle oluşan bir çöküşü ortaya çıkardı. - Eksik Gönderilenler Klasörü: Bir E2E testi, bir e-posta gönderdikten sonra “Gönderilenler” klasörünü kontrol etti. Başarısız oldu. SMTP üzerinden gönderdiğimizi ama mesajı asla IMAP’e kaydetmediğimizi fark ettik! Uygulama hemen eklendi.
Toplam E2E Testi: 484 Senaryo (Hepsi Geçti)
6. Kalite Kontrol: SonarQube Kapısı
Saat geçti (22:00). Sistem çalışıyordu. Testler geçiyordu. Ama “Üretime Hazır” mıydık? Yerelde SonarQube’u kaldırdık ve bir tarama yaptık.
Soğuk Duş:
- 71 Kod Kokusu (Code Smells)
- %21 Kapsama (gözden kaçırdığımız belirli bir modülde)
- Güvenlik Sıcak Noktası: ID üretimi için
Math.random()kullanılmış.
Temizlik (22:00 - 02:00): SonarQube hatalarına derleme hatası muamelesi yaptık.
- Sıkı Tipler: Her
anyi düzgün bir DTO ile değiştirdik. - Modern JS: Eski
concatları spread operatörleriyle değiştirdik,parseIntiNumber.parseIntyaptık. - Güvenlik:
Math.random()ı kaldırdık ve kripto-güvenli ID üretimi uyguladık. - Birim Testleri: E2E sırasında keşfettiğimiz
appendToSentmetodu için eksik olan 3 birim testini yazdık.
Sonuç: Kapsama: %100.0 | Hatalar: 0 | Kod Kokuları: 0 | Güvenlik Sıcak Noktaları: 0
7. Final: “Tek Komutla” Dağıtım
Ertesi günün şafağı (02:00 - 04:00).
Yapbozun son parçası birleşmeydi. O an, servisler ayrı silolarda çalışıyordu. Her şeyi tek bir docker-compose.yml içinde birleştirdik.
- Problem: Frontend yeni ağda Backend ile konuşamıyordu.
- Çözüm: Dahili Docker DNS takma adlarını (aliases) yapılandırdık.
- Problem: Tohum (seed) betiğindeki Admin kullanıcı karması (hash) geçersizdi.
- Çözüm: bcrypt karmalarını yeniden oluşturduk.
Final İstatistikleri: Tam bir mail sunucusu yığınını başarıyla teslim ettik.
- Toplam Kod: ~18,000 Satır Kod (Frontend + Backend + Altyapı)
- Dil Dağılımı: %68 TypeScript, %21 Vue, %3 Go, %8 Shell/Config
- Test Kapsamı: 484 E2E Senaryosu, Çekirdek Modüllerde %100 Birim Test Kapsamı
- Çıktı: Dağıtıma hazır, Dockerize edilmiş, kendi kendine yeten bir mail sunucusu.
8. ROI: Geleneksel vs. Yapay Zeka Destekli Geliştirme
Bu bölüm harcanan gerçek eforu (Yapay zeka ile 20 saat), geleneksel geliştirmenin gerçekçi bir tahminiyle karşılaştırır.
Ne İnşa Edildi (Envanter)
| Bileşen | Detaylar |
|---|---|
| Go TUI Yükleyici | 450 SATIR, Tek-binary, gömülü web varlıkları |
| Yönetim Paneli (Vue3) | 9 Görünüm, NestJS API (8 modül), JWT auth |
| Webmail İstemcisi (Vue3) | 7 Görünüm, NestJS API (IMAP/SMTP proxy), ekler |
| Docker Altyapısı | 6 servis, 4 Dockerfile, 3 ayrı E2E stack |
| Postfix/Dovecot Konfigürasyonu | TLS, SASL, Sanal alan adları, PostgreSQL backend |
| E2E Testler (Playwright) | 484 test senaryosu, Docker-in-Docker çalıştırma |
| Birim Testler (Jest) | %100 çekirdek kapsama, 8,184 satır test kodu |
Geleneksel Geliştirme Tahmini (Yapay Zeka Olmadan)
Faz 1: Araştırma ve Öğrenme
| Görev | Süre |
|---|---|
| Postfix mimarisini öğrenme | 16 saat |
| Dovecot öğrenme | 12 saat |
| IMAP protokolünü öğrenme | 8 saat |
| SMTP protokolünü öğrenme | 6 saat |
| Docker ağ araştırması | 8 saat |
| Playwright E2E araştırması | 6 saat |
Faz 2: Uygulama
| Görev | Süre |
|---|---|
| Postfix/Dovecot konfigürasyonu | 24 saat |
| Go TUI yükleyici | 16 saat |
| Yönetim Paneli backend | 40 saat |
| Yönetim Paneli frontend | 32 saat |
| Webmail backend | 32 saat |
| Webmail frontend | 28 saat |
| Docker Compose birleştirme | 12 saat |
Faz 3: Test
| Görev | Süre |
|---|---|
| E2E altyapı kurulumu | 16 saat |
| 287 Admin E2E testi yazma | 48 saat |
| 197 Webmail E2E testi yazma | 36 saat |
| Kararsız testleri düzeltme | 16 saat |
| Birim test kapsamı | 24 saat |
Faz 4: Kalite ve Cilalama
| Görev | Süre |
|---|---|
| SonarQube entegrasyonu + düzeltmeler | 12 saat |
| Dokümantasyon | 8 saat |
Karşılaştırma
| Metrik | Geleneksel | Yapay Zeka Destekli | Tasarruf |
|---|---|---|---|
| Araştırma | 56 saat | ~2 saat | %96 |
| Uygulama | 184 saat | ~12 saat | %93 |
| Test | 140 saat | ~4 saat | %97 |
| Kalite | 20 saat | ~2 saat | %90 |
| Toplam | 400 saat | 20 saat | %95 |
400 saat (Geleneksel) vs. 20 saat (Yapay Zeka Destekli). Bu, 50 iş günü (2,5 ay) ile tek bir gün arasındaki farktır.
Neden Bu Kadar Büyük Bir Fark?
- Anlık Alan Bilgisi: Yapay zeka Postfix, Dovecot ve IMAP RFC’lerini biliyordu. Kılavuzları okumak zorunda kalmadım.
- Şablon Kodların Ortadan Kalkması: NestJS/Vue kodunun %80’i yapısaldır. Yapay zeka saniyeler içinde üretti.
- Test Üretimi: 484 E2E testini manuel yazmak haftalar alırdı. Yapay zeka dakikalar içinde üretti.
- Hata Ayıklama Hızlanması: Playwright testleri başarısız olduğunda, Yapay zeka Docker ağ sorunlarını anında biliyordu.
- Bağlam Değiştirme Yok: Yapay zeka tüm kod tabanını hatırladı. “O dosya neredeydi?” diye sormak yok.
Sonuç
Bir fikirle başladık. Yapay zeka ile sıkı bir protokol kurduk. Çekirdeği inşa ettik, Birim Testlerle kapladık, E2E testlerle stres uyguladık ve SonarQube ile cilaladık.
24 saatten kısa sürede sadece kod yazmadık. Bir ürün mühendisliği yaptık.
“Yeşil değilse, bitmemiştir.”