Kod editörü ekranında TypeScript servisi açıkken, arkada kütüphane rafları görülüyor.

Fotoğraf yazar tarafından çekilmiştir. İstanbul, Taksim Atatürk Kitaplığı

Üstte gördüğünüz bir önceki yazımda denediğim vibe coding araçlarına bu kez biraz daha yakından bakacağız. Yapay zekâ araçlarını doğru kullanarak fikrini koda dökerken nelere dikkat etmen gerektiğini, tecrübeli bir kardeşin olarak samimi bir dille anlatmaya çalışacağım.



Peki, MVP Nedir? Neden “Minimum”?

MVP (Minimum Uygulanabilir Ürün), bir ürünü en temel ve çekirdek değeriyle inşa etmektir. Amacı; pazara hızla sürmek, erken kullanıcı geri bildirimi almak ve sonraki geliştirmeleri bu verilere göre şekillendirmektir. Vibe coding felsefesiyle tam uyumludur: Çok az çabayla, çok şey öğrenme aracıdır.



I. Analiz Aşamasını Uzatma: Bankacılık Uygulaması Kadar Detaya Gerek Yok

Sevgili Vibe Coder, aksiyona geçme dürtün harika! Ancak klavyeye dokunmadan önce bir dur ve şu gerçeği hatırla: Her proje, daha fikir aşamasındayken risklidir. Büyük projeler bu riski azaltmak için haftalarca süren Proje Başlatma (Initiation) ve fizibilite çalışmaları yapar. Biz bu süreci hızlandırıyoruz ama atlamıyoruz. Detaylı kısıtlamalarla boğulmak yerine, projenin çekirdek fizibilitesini birkaç saatte netleştirmemiz yeterli.


I.I. Peki Analiz Dokümanı Nedir?

Yazılım projesinin neyi çözdüğünü, kim için çözdüğünü ve hangi temel özelliklere sahip olacağını özetleyen kısa bir rehberdir. Amacı, geliştirme sürecine başlamadan önce projenin kapsamını, hedeflerini ve kısıtlarını netleştirmektir.

Karmaşık sistemlerde bu dokümanlar yüzlerce sayfa olabilir; ancak biz MVP için sadece şu soruların cevabını istiyoruz: “Ne yapıyoruz?” ve “Ne yapmıyoruz?” Bir bankacılık sistemindeki detay seviyesinde değil!

ING Türkiye’de çalışırken IBAN’a transfer ekranı için 30 sayfalık analiz görmüştüm. O tip analizler belli bir standartta yazılır; mesela şöyle:

  • IBAN numerik ve 26 hane olacak.

  • 4 karakterde bir boşluk koyulacak.

  • 26 hane tamamlandıktan sonra IBAN kontrol servisine istek gönderilecek.

  • Para transferi yapılacak müşteri aynı bankadansa kullanıcının ismi bir alttaki isim alanına otomatik yazılacak ve değiştirilemeyecek.

  • Başka banka müşterisiyse ismin baş harfleri görünecek, geri kalanı maskeli biçimde inputun altına yazılacak ve kullanıcının isim girmesi zorunlu olacak…

Bu detay seviyesi, MVP aşamasında bizi boğar, yavaşlatır. Bu karmaşık belgelere (İhtiyaç Analiz Dokümanı/FRD) girmen gerekmiyor. Çok daha basit seviyede bir analiz hazırlaman yeterli. Bu analiz, geliştirme sürecinde dönüp dönüp başvurabileceğin sağlam bir çerçeve olacak.

Merak etme, birkaç saatini ayırsan yeter. Biz vibe coder’ız, dostum.


I.II. Vibe Coder MVP Analizi: Tam Olarak Ne İçermeli?

Biz kendi projemizde sadece temel ekran akışlarını ve vizyonu gösteren 20 sayfalık bir sunum hazırladık. Sana da tavsiyem, uzun Word dosyalarına girmek yerine basit bir PowerPoint veya Google Slaytlar hazırlaman. Bu dokümanın amacı, kapsam kaymalarını (scope creep) önlemek için “Ne yapıyoruz?” ve “Ne yapmıyoruz?” sınırlarını net biçimde çizmektir.

  • Projenin Tek Cümlelik Amacı (The North Star): Projen neyi çözüyor? İnsanlar bu ürünü kullanarak neyi başarabilir?

  • Temel Kullanıcı Tipleri (Persona): Kime yapıyoruz? Kullanıcının neyi başarmak istediğine odaklan.

  • Hikâyelerle Konuşmak: Gereksinimleri [KİM] + [NE istiyor] + [NEDEN] formatında yaz.

  • Kullanıcı Akış Haritası: Projede hangi ekranlar olacak? Kullanıcı hangi özelliklerde vakit geçirecek? (Kayıt, dashboard, detay gibi.)

  • En Kritik Özellikler (User Story): Olmazsa olmaz ana işlevler.

I.III. Pratik Seçimler ve Kısıtlar

  • Vibe Coding Yardımcın: MVP’yi inşa ederken hangi yapay zekâ aracını kullanacaksın?

  • Giriş/Kayıt Kolaylığı: Kullanıcı uygulamaya en zahmetsiz şekilde nasıl girmeli? (E-posta/şifre mi, Google/Apple ile tek tıkla mı?)

  • Gelir Kaynağını Unutma: MVP ücretsiz olsa bile, projenin ileride nereden para kazanacağını şimdiden düşünmelisin.

  • Veri Gizliliği: Hangi kullanıcı verilerini saklayacağız ve nasıl koruyacağız? (Özellikle Türkiye/Avrupa pazarı için kullanıcı sözleşmesi zorunludur.)

  • Dil: Başlangıçta sadece Türkçe mi, İngilizce mi? (MVP’de tek dil tavsiyedir.)

Bu maddeler, vibe coding felsefesiyle uyumlu bir hızda karar almanı sağlar. Sayfa sayfa detaya girmek yerine, sadece kritik yasal ve iş kararlarını kapsama almana yardımcı olur.



II. Vibe Coding’de Kaos Kontrolü: İş Takibi

Tüm planlamayı (analiz) yaptık. Şimdi o planı alıp somut görevlere dönüştürme vakti. Hızla kod yazmaya başlamadan önce, solo bile çalışsan projenin kaos ortamına girmemesi için basit bir iş takibi güzel olur.

Bizim gibi hız odaklı geliştiriciler için Trello (basit bir Kanban aracı) fazlasıyla yeterli.


II.I. Basit Kanban: Maksimum 4 Sütun Kuralı

Büyük kurumsal projelerdeki uzun iş akışlarını unut. MVP hızına uygun, seni sadece odakta tutacak sütunları aç:

  1. To Do (Yapılacaklar): MVP’yi tamamlamak için zorunlu olan, sıraya koyduğun tüm görevler. Tek odak noktan.

  2. In Progress (Geliştiriliyor): Üzerinde çalıştığın görevler. Kart sayısını asla 3'ü geçirme.

  3. Blocked (Cevap Bekleniyor): Bir ekip arkadaşından veya paydaştan yanıt beklediğin durumlar için kullanılır, darboğazları netleştirir.

  4. Done (Tamamlandı): Bitirdiğin görevler, motivasyon kaynağın.

Ideas/Backlog: Aklına gelen ama MVP’ye girmemiş tüm harika fikirlerin bekleme listesi.

II.II. Hız Odaklı Görev Kartları

  • Başlık: Her zaman bir kullanıcı hikâyesi formatında olsun. (Örn: Kullanıcı, Google hesabı ile uygulamaya giriş yapabilmeli.)

  • Açıklama: Sadece görevi tamamlamak için gereken en kritik bilgiyi içersin.

Tahmin (Efor): Görevleri 2–4 saatlik küçük parçalara ayır. (Ben kendi projemde efor tahminine gerek duymadım ama sen büyük görevleri parçalayabilirsin.)



III. Kullanıcı Deneyimi: Tasarım Öğrenmek Yerine Sezgilerini Kullan

Ne istediğine tamamen karar verdikten ve görevlerini Trello’ya attıktan sonra ufak ufak girişebiliriz. Nasıl bir ürün üretirsen üret -bir arayüze sahipse- kullanıcısız bir işe yaramaz. Yani tasarımının bir albenisi olmak zorunda.

Not: Ürünün bir kullanıcı arayüzüne (UI) sahipse (B2C, B2B SaaS, mobil uygulama gibi) aşağıdaki tasarım adımları önemlidir. Ancak mesela bir web sitesini izleyip e-posta atan bir arka plan servisi (headless service) veya sadece bir API geliştiriyorsan bu adımı atlayıp doğrudan kodlama (IV. Bölüm) aşamasına geçebilirsin.

Sana Stanford Üniversitesinde anlatılan Design Heuristics kanunlarını yala yut demiyorum. Enine boyuna tasarım öğreneceksin diye bir şey yok. Sadece temel bazı prensipleri uygula: basit düşün, içgüdülerini dinle. Gözünü tırmalayan bir tasarım yapma, yeterli.

Dribbble, Behance gibi platformlardan ilham alabilirsin. Tasarım öğrenmek için saatler hatta günler harcamak yerine gözünü eğitmek için 15 dakika ayır ve vibe coding’in gerektirdiği hızla yoluna devam et.


Yapay Zekâ Tasarımda Bile Yanında

Zaten bazı araçlar tasarımda bile artık belli bir seviyenin üstünde yetenekli. Tabii ki bir tasarımcının yerini asla tutamazlar ama aklındaki projenin kabataslak bir görüntüsünü giriş seviyesinde de olsa oluşturabilirler.

Done better than perfect.

Gerçekten doğru: Bitmiş, mükemmelden iyidir. Çünkü mükemmelin sınırı yok. Bugün çok güzel gelen bir şey, yarın kötü görünebilir. Scrum’da da böyle.



IV. Yapay Zekâ Kodu: “Çöpü Ayıklama” ve Ustalık Dokunuşu

Yapay Zekâ Şahane Fikir Verdi, Ama Asıl İş Şimdi Başlıyor

Biz Lovable kullandık. Sadece görsel olarak çekici değil, aynı zamanda işlevsel bir temel React/Tailwind kodu da verdi. Dakikalar içinde çalışan bir çıktı elimizdeydi; ancak tüm veriler, mantık ve arayüz tek bir dosyanın içindeydi! Benim için kodun çalışması yetmez: Bakımı kolay olmalı, test edilebilir olmalı.

Kodu 3 ay sonra bile rahat anlayabilmek ve AI saçmaladığında neyin nerede olduğunu hızlıca çözebilmek için Lovable’ın ürettiği bu ham dosyaları alıp gerçek bir yazılım projesine dönüştürmek zorundaydım. Ama React bilmiyordum. İmdadıma Google Antigravity yetişti.

Not: Eğer amacın sadece fikri ham hâliyle test etmekse veya kod bilmiyorsan bu adımı atlayıp AI koduna güvenebilirsin. Ama bu kod böyle kalırsa büyümez!

Backend için Supabase’i seçtim. DB, auth ve dosya depolama işlerini tek bir serverless platformdan hallederek inanılmaz zaman kazandım.


IV.I Monolit’i Ayırmak (Veri, Sunum ve Mantık Katmanları)

Yapay zekâ tembeldir. Onun ürettiği ilk kodda tüm UI, taklit veri, filtreleme mantığı aynı dosyanın içindeydi! 1000–1400 sayfalık karmakarışık sınıflar üretmişti! İşte vibe kodu üzerindeki ustalık dokunuşları:

  • Veriyi Ayırmak: sports ve categories gibi sabit verileri ayrı tablolara taşıdım, foreign key’ler ile ilişkilendirdim.

  • Katman Mimarisi: Basit bir MVVM (Model-View-ViewModel) mantığı kurarak service (veri çekme) ve hook (view logic) katmanlarını ayırdım.

  • Bileşenleri Ayırmak: FilterSection ve TechCard gibi parçaları ana sayfadan koparıp, her yerde kullanılabilecek bileşenlere çevirdim.

  • Hızlı Tablo Oluşturmak: TechPost modelini oluşturduktan sonra, Gemini’ye “Supabase'de bu objeye karşılık gelecek tabloyu yaratacak SQL query'yi ver” diyerek tabloyu hızla oluşturdum.

  • Veri Akışını Temizlemek: useTech hook’u, artık veriyi doğrudan koddan okumak yerine, dışarıdaki service katmanından çekiyor ve veri üzerinde gerekli manipülasyonu yapıyor.

  • Skeleton Ekran Eklemek: isLoadingTechContent, veri beklerken kullanıcıya iskelet ekran (skeleton) göstermek için var. Bu, tecrübeli bir yazılımcının el izidir. Hiçbir dil modeli bu geliştirmeleri kendi kendine yapmaz, yapmayacak; dürtmek zorundasın.

  • Aramada Debounce Kullanmak: Basitçe Enter’a basıp arama yapmak yerine, kullanıcının yazmayı bitirmesini bekleyen (300ms) bir useEffect ve setTimeout döngüsü kurdum. Bu, kullanıcı deneyimini iyileştirir. Bir basit ama hoş ve profesyonel iz daha.

  • Performans Dokunuşu: Özellikle filtreleme mantığında React’ın useMemo özelliğini kullanarak gereksiz yeniden render işlemlerini ve hesaplamaları önledim.

TechPost:

typescript
export type TechPost = {
  id: number
  title: string
  image?: string
  summary: string
  SportCategory?: Pick<SportCategory, "category"> | null
  Profile?: UserProfile | null
}

Yeni TechBlog:

javascript
const TechBlog = () => {
  const [sportFilter, setSportFilter] = useState("all")
  const { sportCategories } = useSportCategories()

const selectedSportCategoryId = useMemo(() => {
    if (sportFilter === "all") return undefined
    return sportCategories.find((c) => c.sport_category === sportFilter)?.id
  }, [sportFilter, sportCategories])
const { techContent, isLoadingTechContent } = useTech(selectedSportCategoryId)
  const sports = sportCategories.map((category) => category.sport_category)
return (
    <MainLayout>
      <FilterSection
        title="Sport Category"
        items={sports}
        selectedValue={sportFilter}
        onValueChange={setSportFilter}
        allLabel="All Sports"
      />
      <h1 className="text-3xl font-bold">TechBlog</h1>
      <Input placeholder="İçerik ara..." value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} />
      <div className="grid sm:grid-cols-2 gap-4">
       {techContent.map((content) => <TechCard key={content.id} {...content} />)}
      </div>
    </MainLayout>
  )
}
export default TechBlog

techService:

typescript
export const getTechContent = async (
  sportCategoryId: number | undefined,
  userId: string
): Promise<TechPost[]> => {
  let query = supabase.from("TableName").select("*, Category(category)").order("created_at", { ascending: false })
  if (sportCategoryId) {
    query = query.eq("sport_category_id", sportCategoryId)
  }
  const { data, error } = await query
  return data as TechPost[]
}


V. SOLID?

  1. Tek İş Tek Modül (Single Responsibility): TechBlog bileşeni sadece ekrandan, service (servis) katmanı veri çekmekten, hook’lar ise arayüz mantığından sorumlu. Yani her parçanın tek bir varoluş sebebi var.

  2. Geleceğe Açık (Open/Closed): Yeni bir filtre mi eklemek istiyorsun? FilterSection bileşenini ellemene gerek yok, sadece ona yeni veri yolla. İşte bu: Kodun esnekliği sağlandı.

  3. Soyutlama (Dependency Inversion): Belki de en önemlisi bu: Ben artık arayüzü, doğrudan veri kaynaklarına bağlamadım, araya useTech gibi soyut bir katman koydum. Bu ne demek? Demek ki yarın proje büyüse, backend’i (veri kaynağını) komple değiştirsek, hatta servis yazsak bile arayüz bileşenleri bundan etkilenmeyecek. Yapay zekânın yazdığı kod, başka bir yapay zekâ sayesinde daha sağlam ve esnek hâle geldi.

Bu yazı yayınlanmadan önce projeye 90 100 saat vermiştim. Anlattıklarımdan çok daha karmaşık işlerin altından bile kod yazmadan çıktım. Bu da tabii ki SOLID sayesinde oldu.

Vibe Coding + Ustalık = Sürdürülebilirlik



VI. Kod Bilmeyen Vibe Coder

  1. Hız Kazanmaya Odaklan: Sen bir kod uzmanı değilsen IV. bölümdeki derin mimari adımları atmak zorunda değilsin. Amacın sadece fikri test etmek olmalı. Vibe coding’in temel sözünü tut: Yapılana odaklan, mükemmel olana değil.

  2. Güven ve Yönlendir: Gemini’den SQL al, Lovable’ın kodunu kullan. Senin görevin mühendislik yapmak değil, projenin vizyonunu yönetmek ve AI’ı doğru yönlendirmektir.

  3. Hemen Yayınla: MVP’yi olabildiğince ham hâlde yayınla. Kullanıcı geri bildirimini topla. Eğer fikrin tutarsa ve ilk kullanıcıları çekersen işte o zaman bu kodu temizleyecek ve SOLID prensiplerine uyduracak bir “Senior Vibe Coder” (freelancer veya ortak) bulman gerektiğini anlarsın.

  4. Devam Et: Bu yazıda anlattığım analiz ve Trello (kaos kontrolü) adımlarını atlamadan fikrini koda dökmeye devam et.



Sonuç

Gördüğün gibi, yapay zekâ sana hızla çalışan bir taslak verir. Ama o taslağı alıp yarın büyüyebilecek, binlerce kullanıcının trafiğini kaldırabilecek SOLID prensiplerine uygun, gerçek bir yapıya oturtmak benim gibi tecrübeli bir senior’ın işiydi.

Unutma: Vibe coding bize temeli 1 saatte atmamızı sağladı. Ama ürünü sürdürülebilir kılan, ustalığa yapılan yatırımdır!

Bu yazıda yaptığım projeyi tam olarak açıklayamıyorum. Yayına aldığımızda farklı yazılar yazacağım. Görüşmek üzere.