Neden Sıfırdan Yaptım?
Bir mühendisin portfolyosu artık çoğunlukla bir "şablon doldurma" işi haline geldi. WordPress, hazır portfolyo platformları, Notion sayfaları — hızlı ve iş görür. Ama ben farklı bir şey istedim: kendi yazdığım sistemi, kendi mimari kararlarımı, hatta kendi AI chatbot'umu içeren tam yığın bir site.
Sebepleri açık:
- Vitrin değil, kanıt: Yapabildiğim şeyleri anlatan değil, gösteren bir site.
- Öğrenme alanı: Kendi production deployment'ım, kendi cache stratejim, kendi auth katmanım.
- Çalışan bir şey: Site ziyaretçileri benim chatbot'umla konuşabiliyor — ve bu mimari Mavi Çatal projesinde geliştirdiğim RAG pipeline'ın aynısı.
İki buçuk hafta önce sıfır kod vardı. Bugün canlıda.
Stack Seçimleri ve Mantığı
Her teknolojinin "neden bunu seçtim" hikayesi var:
Backend — .NET 10 + EF Core 10: C#'ın type system'i ve ASP.NET'in middleware pipeline'ı modern API mühendisliği için zarif araçlar sunuyor. Result<T> pattern ve ProblemDetails, hata yönetimini disiplinli tutuyor. Nullable reference types ve source generators refactoring esnekliği veriyor.
Frontend — Next.js 16 + Tailwind 4: SSR + ISR + Server Components üçlüsü hem SEO hem performance için anlamlı. Tailwind 4'ün @theme direktifi design token tabanlı çalışmayı sağlıyor — tek yerden tüm renkleri ve spacing'i yönetebiliyorum.
AI — Python + LangGraph + pgvector: Chat bot için "tek bir LLM call" yetmedi. RAG retrieval, sorgu yeniden yazma, tool calling, streaming — bunları graph üzerinde modellemek tek bir prompt'a sığdırmaktan çok daha temiz. LangGraph'ın state machine yaklaşımı akışı kodla değil grafikle düşünmemi sağlıyor.
Database — PostgreSQL + pgvector: Embedding'ler ve normal veri tek yerde. Ayrı bir vector database (Pinecone, Weaviate) kurmaya gerek yok.
Deploy — DigitalOcean + Supabase + Vercel: Frontend Vercel'in Hobby tier'ında ücretsiz, DB Supabase free tier yeterli, backend + chat bot kendi VPS'imde — systemd + nginx + Let's Encrypt. Aylık maliyet: yaklaşık 20 dolar.
Ders 1: AI Grader'ı Kaldırmak Halüsinasyonu Çözdü
Chat bot'un ilk halinde "gelişmiş" bir RAG mimarisi vardı:
- Sorgu yeniden yaz
- Embedding üret
- Top-k chunk retrieve et
- Bir LLM ile "bu chunk gerçekten alakalı mı?" diye derecelendir (grader)
- Sadece alakalı olanlarla cevap üret
Mantıklı geliyor, değil mi? Daha kaliteli bağlam = daha iyi cevap.
Pratikte: grader çok katıydı. "Mahmoud'un en başarılı projesi nedir?" sorusuna içinde LoomAI'dan bahseden chunk'lar geldi ama grader bunları "tam olarak 'en başarılı' kelimesini içermiyor" diye reddetti. Boş bağlamla bırakılan LLM kendine ait şeyler uydurdu — yani halüsinasyon başladı.
Çözüm: Grader'ı tamamen kaldırdım. Sadece retrieve → generate. Sonuç: 10/10 spesifik proje ismi doğru cevaplandı, halüsinasyon sıfır.
Ders: "Daha fazla AI katmanı = daha iyi sonuç" otomatik doğru değil. Bazen az olan kazanır. Mimari kararlarda ölçtükten sonra konuş.
Ders 2: Production'a Alış — 12 Hata Beni Yetiştirdi
Site geliştirme bir, production'a alma başka bir oyun. 12 farklı sorunla çarpıştım. Bazıları:
- Supabase'in IPv6'sı: VPS'imin IPv6'sı yok, direct connection patlıyordu. Çözüm: Session Pooler.
- JSON parse hatası:
appsettings.Production.jsonokumadı çünküopenssl rand -base64çıktısında newline vardı.| tr -d '\n'ile temizledim. - pgvector yanlış schema:
extensionsschema'sına kurulmuş,public.vector(1536)referansı bulamıyordu.DROP EXTENSION; CREATE EXTENSION ... WITH SCHEMA public;ile çözdüm. - CSP block: Frontend
connect-srcdirective'inde sadece localhost vardı. Login'de "Bir sorun oluştu" hatası aldım. - Şifredeki
#: Supabase şifremde#vardı,.envdosyasında yorum karakteri olarak algılandı. URL encode ettim (%23).
Ders: Production'a alış her zaman tahmin ettiğinden daha uzun sürer. Çünkü "bilgisayar bilimi" değil, production mühendisliği — laboratuvarda olmayan, sadece gerçek dünyada çıkan şeyler.
Ders 3: Aynı Mimariyi İki Yerde Kullandım
Chat bot'umun altyapısı, daha önce Mavi Çatal projesinde (restoran AI asistanı) geliştirdiğim RAG pipeline'ının aynısı. Tekrar yazmak yerine jenerik hale getirdim:
- Knowledge base bir text dosyası, regen edilebilir
- Chunk'lama parametreleri config'te
- Embedding modeli pluggable
- Sistem prompt'lar TR/EN olarak ayrı
Sonuç: Yeni bir RAG projesi için sıfırdan başlamak gerekmez.
Ders: İkinci yere bir şey kopyalayınca, mimarinin doğru yere taşınmadığını fark edersin. Üçüncü yerde refactor zamanı.
Ders 4: Admin Panel İlk Günden Olmalı
Site'nin Admin paneli olmadan içerik eklemek için ya doğrudan SQL yazıyor ya da seed dosyaları çalıştırıyordum. Faz 8'de Admin paneli devreye girdiğinde, içerik üretim hızı 3x arttı — bir blog yazısı eklemek artık SQL yazmaktan çok daha kolay.
Ders: "Önce ürünü build et, panel sonra" diye düşünenler ben dahil. Yanlış. Panel olmadan içerik üretmek aşırı yavaş ve motivasyon kırıcı.
Ders 5: Polyglot Stack, Mikroservis Değil
Frontend Next.js, backend .NET, AI Python — üç farklı dil, üç farklı runtime. İlk başta endişelendim: "fazla parçalı mı?"
Ama her birinin kendi alanında en iyisi olduğunu deneyimledim:
- Next.js → web UI ve SSR için sınıfta üstün
- .NET → kurumsal API ve type safety için olgun
- Python → AI/ML ekosistemi için tartışmasız
Aynı dilde her şeyi yazmaya çalışmak yerine, her sorumluluğu en uygun stack'e verdim. Bu mikroservis değil — tek bir ürün, üç dil. "Polyglot monolith" diyebiliriz.
Ders: Mikroservis değil monolith değil; doğru aracı doğru iş için seçmek.
Bundan Sonrası
Site canlı ama bitti değil. Sıradakiler:
- Daha fazla blog post — bu ilkti
- EN knowledge base'i gerçek çeviri ile zenginleştir (şu an TR'nin ikizi)
- UptimeRobot monitoring kur
- Performance'ı gerçek kullanıcı metrikleriyle ölç
Geri bildirim her zaman hoş geldi. Sağ alttaki chatbot'a "site nasıl?" diye sorabilir, ya da bana doğrudan mail atabilirsin: mahmuod.almuhammad@gmail.com.
Okuduğun için teşekkürler — umarım kendi projende işine yarar bir şeyler vardır.
