Yirmi yıldır sektörde çalışınca, kurumsal dünyanın getirdiği alışkanlıklar ister istemez yan projelerinize de sızıyor. Özellikle bir üretim ERP’si üzerinde uzun süre çalıştığımda, tedarik zinciri süreçlerinin veri akışını yönetmenin ne kadar karmaşık olabileceğini birebir gördüm. Malzeme ihtiyaç planlamasından sevkiyat optimizasyonuna, her adım ayrı bir veri akışı, ayrı bir entegrasyon noktası demekti.
Fakat kendi yan ürünlerime döndüğümde, bu kurumsal düşünce yapısının beni gereksiz bir karmaşıklığa sürüklediğini fark ettim. Yan projelerin doğası gereği hızlı prototipleme ve minimum eforla değer yaratma ihtiyacı varken, ben kendimi bazen gereksiz yere enterprise mimarileri düşünürken buluyordum. Bu yazıda, yan projelerde tedarik zinciri data flow yönetimini neden abarttığımızı ve daha sade yaklaşımların nasıl daha verimli olduğunu kendi deneyimlerimle anlatacağım.
Büyük Resimden Küçük Detaylara Geçişin Yanılgısı
Kurumsal yazılım geliştirmede, genellikle büyük resimle başlarız: iş akışları, entegrasyon noktaları, veri tutarlılığı, ölçeklenebilirlik ve hata toleransı. Bir üretim ERP’sinde çalıştığımda, siparişten faturaya kadar olan tüm süreci düşündüm; satın alma, üretim, stok yönetimi, sevkiyat gibi her bir modülün kendi içinde nasıl bir veri akışı olması gerektiğini tasarladım. Bu, doğal olarak karmaşık Event Sourcing, CQRS gibi kalıpları ve birden fazla mikroservisi beraberinde getiriyordu.
Ancak yan projelerimde, örneğin kendi finansal hesaplayıcılarımın backend’ini geliştirirken, aynı zihniyetle yola çıktığımda bir duvara çarptım. Birkaç tabloyu birbiriyle ilişkilendiren basit bir hesaplama motoru için neden bir mesaj kuyruğu kurmam gerektiğini sorgulamaya başladım. Kurumsal bir ERP’nin yüzlerce tablosu ve binlerce iş kuralı varken, kendi projemde belki 10-15 tabloyla işlem yapıyordum. Oradaki karmaşıklık, buradaki basit bir ihtiyaca doğrudan uygulandığında sadece zaman ve enerji kaybına neden oluyordu. Bu benim için ölçeklenebilirlik ihtiyacı ile geliştirme hızı arasındaki net bir trade-off oldu. Kurumsal bir sistemde yüksek hacimli işlemlerde milisaniyeler konuşulurken, yan projede saniyelerin bile sorun olmadığı durumlar çok fazlaydı.
Geçen yıl bir yan ürünümün backend’i için veri akışını tasarlarken, geçmişteki bir müşteri projesinde karşılaştığım bir senaryo aklıma geldi. Müşteri projesinde, tedarik zinciri entegrasyonu için birden fazla harici API’den veri çekip, bunları merkezi bir veri gölünde işleyip, ardından farklı departmanlara dağıtan kapsamlı bir ETL süreci yazmıştım. Bu süreç, hatırı sayılır bir veri hacmini işliyor ve çok sayıda farklı sisteme entegrasyon sağlıyordu. Yan ürünümde ise, kullanıcıların basit bir liste oluşturup görev eklemesi gerekiyordu. Bu iki senaryo arasındaki farkı göz ardı edip, yan üründe de benzer bir “veri gölü” mantığıyla ilerlemeye çalıştığımda, günlerce gereksiz yere altyapı kurulumuyla uğraştım. Oysaki PostgreSQL’de basit bir INSERT ve SELECT işlemi, tüm ihtiyacımı anında karşılıyordu. Bu durum, özellikle yüksek performans beklenen üretim ortamlarında PostgreSQL’in B-tree indexlerinin veya GIN indexlerinin ne kadar kritik olduğunu düşündüğümde, yan projelerde ise connection pool tuning gibi daha temel optimizasyonların genellikle yeterli olduğunu gösteriyor.
Gerçek Bir Üretim ERP’sindeki Data Flow ve Yan Proje Farkı
Bir üretim firmasının ERP’sinde çalışırken, “satın al-üret-sevk et-faturalandır” döngüsünün veri akışı inanılmaz detaylıydı. Örneğin, bir siparişin alınmasından, hammaddenin tedarikçiden depoya girmesine, üretim hattında işlenmesine, kalite kontrol süreçlerinden geçmesine ve nihayet müşteriye sevk edilip faturasının kesilmesine kadar her adımda veri akışı kritikti. Burada stok seviyeleri, üretim çizelgeleri, kalite kontrol sonuçları ve finansal kayıtlar arasında anlık ve tutarlı bir bilgi akışı sağlamak zorundaydık. Bu, bazen yüzlerce farklı veri noktasının eşzamanlı olarak güncellenmesini gerektiriyor, hatta IFRS gibi uluslararası finansal raporlama standartlarına uygun kayıtların tutulmasını zorunlu kılıyordu. Bu tür bir sistemde, veri tutarlılığı ve işlemsel bütünlük için Event Sourcing, Saga Pattern veya distributed transaction gibi karmaşık mimariler kaçınılmazdı.
Kendi yan ürünümde, basit bir envanter takip sistemi geliştirdiğimde ise durum tamamen farklıydı. Belki 20-30 ürünü takip ediyordum, stok hareketleri günde birkaç kez oluyordu ve finansal entegrasyon gibi bir derdim yoktu. Burada, bir ürünün stok adedini güncellediğimde, bunu anlık olarak tek bir veritabanı işlemiyle yapmak yeterliydi. Bir üretim ERP’sinde IFRS entegrasyonu için kapsamlı bir ETL scripti yazarken, kendi yan ürünümde basit bir UPDATE sorgusuyla tüm ihtiyacımı karşılıyordum. Örneğin, bir UPDATE products SET stock_quantity = stock_quantity - 1 WHERE id = 123; sorgusu, benim için tüm “tedarik zinciri veri akışı” yönetimini ifade ediyordu.
-- Üretim ERP'sinde, karmaşık bir sipariş işleme senaryosunun parçası:
BEGIN;
UPDATE stock_movements SET quantity = quantity - 5 WHERE product_id = 101 AND warehouse_id = 1;
INSERT INTO production_orders (product_id, quantity, status) VALUES (101, 5, 'in_progress');
INSERT INTO audit_logs (event_type, details) VALUES ('production_start', 'Product 101, quantity 5');
-- ... Daha onlarca farklı tabloya insert/update işlemi ...
COMMIT;
-- Kendi yan projemde, basit bir stok düşme işlemi:
UPDATE products SET stock_quantity = stock_quantity - 1 WHERE id = 123;
Bu iki senaryo arasındaki temel fark, gereksinimlerin ölçeği ve karmaşıklığıydı. Kurumsal bir ERP’de, bir veri akışının kesintiye uğraması milyonlarca dolarlık kayıplara yol açabilirken, benim yan projelerimde en kötü ihtimalle ben kendim bir hatayı manuel olarak düzeltebilirdim. Bu durum, PostgreSQL gibi güçlü veritabanlarının, basit ve iyi tasarlanmış tablolarla bile ne kadar fazla yükü kaldırabildiğini bana tekrar gösterdi. Yan projelerde, journald’nin log yönetimi ve systemd unit’lerinin basit servisleri ayağa kaldırması gibi temel Linux araçları genellikle yeterli oluyor. [İlgili: Basit Linux Servis Yönetimi]
“Abartı” Nerede Başlar: Mikroservisler ve Asenkron İletişim
Yan projelerde “abartı”nın başladığı ilk yerlerden biri bence mikroservis mimarisi ve asenkron iletişim kurma hevesi. Kurumsal dünyada, büyük ekiplerin farklı iş alanlarına odaklanabilmesi, bağımsız deployment yapabilmesi ve farklı teknoloji yığınlarını kullanabilmesi için mikroservisler bir zorunluluk haline gelebiliyor. Bir bankanın iç platformunda çalışırken, farklı departmanların kendi servislerini geliştirmesi ve birbirleriyle mesaj kuyrukları aracılığıyla iletişim kurması, ölçeklenebilirlik ve esneklik açısından hayatiydi. Burada, bir işlem 3-4 farklı servisten geçebiliyor ve her servisin kendi veritabanı olabiliyordu. Bu durum, özellikle event-sourcing ve transaction outbox pattern’lerinin ne kadar kritik olduğunu gösteriyordu.
Ancak kendi Android spam uygulamamda, gelen SMS’leri filtrelemek ve bir veritabanına kaydetmek gibi basit bir işlem için neden ayrı bir “SMS işleme servisi” ve “veri kaydetme servisi” kurup aralarına RabbitMQ ya da Kafka koymam gerektiğini sorgulamaya başladım. Gelen her SMS için araya giren ek gecikme, kullanıcı deneyimini doğrudan etkileyebilirken, bu karmaşık yapıyı kurmak bana yalnızca fazladan iş çıkarıyordu. Sonuçta, bu veri akışını yönetmek için direkt olarak uygulama içindeki SQLite veritabanını kullanmak çok daha hızlı ve basit bir çözüm oldu.
Deneyimlerime göre, yan projelerde asenkron iletişimin gerçekten gerekli olduğu durumlar çok nadirdir. Genellikle bir görevi arka planda çalıştırmak için basit bir threading ya da bir cron job yeterli olur. Mesela, kendi siteme yaptığım basit bir veri toplama aracı için, her saat başı çalışan bir systemd timer ve bir Python script’i kullanıyorum. Bu script, belirli bir web sitesinden veri çekip PostgreSQL veritabanıma kaydediyor. Herhangi bir mesaj kuyruğu veya karmaşık bir servis mimarisine ihtiyaç duymadan, bu işlem tıkır tıkır çalışıyor. Eğer bir hata olursa, journalctl -u benim-servisim.service komutuyla kısa sürede ne olduğunu görebiliyorum. Bu basitlik, benim için yan projelerin en büyük avantajlarından biri. Zira, büyük sistemlerde container memory limit’lerini ayarlamak, build OOM hatalarını çözmek gibi konularla zaten boğuştuğum için, yan projelerde bu tip dertlerden uzak durmayı tercih ediyorum.
Doğrudan SQL ve Basit API’ler: Unutulan Verimlilik
Bazen kurumsal dünyadan gelen alışkanlıklar yüzünden, en basit sorunlara bile kompleks çözümler üretme eğiliminde oluyoruz. Tedarik zinciri veri akışı yönetimini düşündüğümde, aklıma hemen API Gateway’ler, veri transformasyon katmanları, mesaj kuyrukları ve orkestrasyon motorları geliyor. Oysaki yan projelerde, çoğu zaman doğrudan SQL sorguları ve basit RESTful API’ler, ihtiyacımızın büyük bir kısmını hatta tamamını karşılayabiliyor.
Kendi finansal hesaplayıcılarımın backend’ini geliştirirken, kullanıcıların girdilerini alıp birkaç matematiksel işlemden sonra sonuçları göstermem gerekiyordu. Bu işlem için birden fazla servisi bir araya getirmek yerine, FastAPI ile yazılmış tek bir API endpoint’i ve PostgreSQL veritabanındaki basit SELECT ve INSERT sorguları yeterli oldu. Örneğin, üç farklı tabloyu (girdiler, ara sonuçlar, nihai sonuçlar) bir JOIN ile birleştiren bir sorgu, göz açıp kapayıncaya kadar çalışıyordu. Bu hız ve basitlik, bana Kafka gibi dağıtık bir mesajlaşma sistemi kurmanın veya event-driven mimari tasarlamanın ne kadar anlamsız olduğunu gösterdi.
-- Kendi finansal hesaplayıcımın basit bir veri çekme sorgusu:
SELECT
u.username,
i.input_value,
r.calculated_result
FROM
users u
JOIN
inputs i ON u.id = i.user_id
JOIN
results r ON i.id = r.input_id
WHERE
u.id = :user_id AND i.calculation_date = CURRENT_DATE;
PostgreSQL’in gücü, doğru index stratejileri (B-tree, GIN, BRIN) ve connection pool tuning ile basit sistemlerde bile şaşırtıcı derecede iyi performans gösterebiliyor. Çoğu yan projede N+1 sorgu problemi veya eager-load patlamaları gibi ORM tuzaklarına düşmemek için dikkatli olmak, karmaşık bir mimari kurmaktan çok daha verimli. Bir müşteri projesinde karşılaştığımız, yanlış bir ORM konfigürasyonu yüzünden her kullanıcı isteğinde aşırı sayıda SQL sorgusu çalıştıran bir durum olmuştu. Bu durumu çözmek için ORM ayarlarını optimize etmek, yeni bir veri akışı sistemi tasarlamaktan çok daha hızlı ve etkiliydi.
Bu, aynı zamanda sistem güvenliği açısından da bir avantaj sağlıyor. Daha az hareketli parça demek, daha az güvenlik açığı potansiyeli demek. fail2ban paternlari ile Nginx reverse proxy’min önünü korumak, rate limiting uygulamak ve JWT/OAuth2 gibi basit kimlik doğrulama mekanizmaları kullanmak, bir yan proje için genellikle yeterli oluyor. Karmaşık bir veri akışı mimarisi, DDoS mitigation katmanları veya kernel module blacklist gibi konuları düşünmeyi gerektirirken, basit bir CRUD API’si ile bu tür dertlerden uzak kalıyorum. [İlgili: Nginx ile Basit Güvenlik Önlemleri]
Observability ve Hata Yönetiminde Gerçekçilik
Kurumsal sistemlerde observability (izlenebilirlik) ve hata yönetimi, projenin en kritik parçalarından biridir. Metrikler, loglar, trace’ler, SLO’lar (Service Level Objectives) ve error budget’lar olmadan büyük bir sistemi ayakta tutmak neredeyse imkansızdır. Bir üretim ERP’sinde, geç sevkiyat raporunun neden eksik geldiğini bulmak bazen günlerimi alabiliyordu. Bu durum, veri akışının onlarca farklı servisten geçmesi, her servisin kendi logunu üretmesi ve bu logları merkezi bir sistemde birleştirip analiz etme zorunluluğundan kaynaklanıyordu. Gece yarısı düşen bir WAL rotation alarmı bile, tüm sistemin sağlığını etkileyebiliyordu.
Yan projelerde ise bu seviyede bir observability çoğu zaman gereksiz bir yük. Kendi yan ürünümün backend’inde bir hata olduğunda, genelde tek bir log dosyasına bakmak veya journalctl çıktısını kontrol etmek yeterli oluyor. Bir müşteri projesinde birkaç mikroservis arasındaki zincirleme hatayı debug etmek saatlerimi alırken, kendi yan ürünümde basit bir try-except bloğu ve bir print ifadesiyle sorunu kısa sürede çözdüğüm durumlar oldu. Bu durum, journald rate limit’lerinin veya cgroup memory.high yumuşak limitlerinin yan projelerde ne kadar işlevsel olduğunu gösteriyor.
Benim bakış açıma göre, yan projelerde hata yönetimi daha pragmatik olmalı. Bir hatanın oluşma sıklığı ve etkisi düşükse, yani günde bir kez olan ve kullanıcıyı çok etkilemeyen bir durumsa, bunun için karmaşık bir izleme ve uyarı sistemi kurmak yerine, ara sıra loglara göz atmak yeterli olabilir. Geçen ay kendi yan ürünümde bir OOM-killed hatası aldığımda, bunu hemen journalctl’den görüp polling-wait mekanizmasına geçmek kısa sürdü. Bu tür “olur o kadar” hataları, yan projelerin doğal bir parçası. Kurumsal bir sistemde ise bu tür bir hata, anında paging ve kritik alarm anlamına gelirdi. Bu farkı anlamak, yan projelerde doğru araçları seçmek için kritik. Zira, auditd ile dosya bütünlük monitoring’i veya SELinux/AppArmor profilleri gibi derinlemesine güvenlik ve izleme mekanizmaları, yan projeler için genellikle fazla detaylı kalır.
Zaman ve Enerji Yönetimi: Yan Projelerin Gerçek Değeri
Yan projeler benim için sadece kod yazmaktan ibaret değil; aynı zamanda yeni teknolojileri denemek, farklı fikirleri hayata geçirmek ve kişisel gelişimime katkıda bulunmak anlamına geliyor. Bu projelerin gerçek değeri, hızlı iterasyon yapabilmek, deneysel yaklaşımlar sergilemek ve mümkün olan en kısa sürede bir şeyler ortaya koyabilmektir. Tedarik zinciri veri akışı yönetimini kurumsal bir gözle abarttığımızda, aslında bu temel değerleri göz ardı etmiş oluyoruz.
Bir AI ile üretim planlama projesinde, aylarca karmaşık bir veri akışı mimarisi ve entegrasyonlar üzerinde çalıştım. Sonuçta ortaya çıkan MVP değerliydi ama süreç çok uzundu. Diğer taraftan, kendi Android spam uygulamamda basit bir özellik eklemek kısa sürdü ve anında kullanıcı geri bildirimleri aldım. Bu hızlı geri bildirim döngüsü, motivasyonumu artırdığı gibi, projenin yönünü daha net belirlememe de yardımcı oldu. Yan projelerde, feature flag’ler veya dark launch gibi karmaşık deployment stratejileri yerine, basit bir blue-green veya rolling deploy, hatta manuel rsync ile deployment yapmak bile yeterli olabiliyor.
Yan projelerde “olur o kadar” mantığıyla hareket etmek, beni çoğu zaman daha iyi sonuçlara ulaştırdı. Karmaşık bir veri akışı mimarisi tasarlamak yerine, mevcut araçları en verimli şekilde kullanmaya odaklandım. Kurumsal bir ERP’de gecikmiş bir raporun sebebini bulmak tüm veri akışını baştan sona incelemeyi gerektirirken, kendi yan ürünümde benzer bir raporlama ihtiyacı için basit bir SQL sorgusu ve bir web arayüzü yeterli oluyor. Bu, benim için sadece zaman tasarrufu değil, aynı zamanda zihinsel bir rahatlama da sağlıyor. Sonuçta, bu projeler genellikle tek kişilik orkestralar olduğu için, CI/CD reliability, SLO ve error budget yönetimi gibi konuları kurumsal seviyede düşünmek, burnout riskini artırıyor.
Sonuç: Yan Projelerde Kontekst Önemlidir
Yan projelerde tedarik zinciri data flow yönetimini abartmak, kurumsal deneyimlerimizin bir yansıması olabilir. Ancak bu, çoğu zaman gereksiz bir karmaşıklığa ve zaman kaybına yol açar. Kendi tecrübelerimden yola çıkarak şunu söyleyebilirim: bir üretim ERP’sindeki devasa veri akışını yönetme pratiği ile, kendi küçük çaplı bir yan ürünümdeki veri akışını yönetme ihtiyacı arasında dağlar kadar fark var.
Yan projelerin ana amacı hızlı öğrenme, deneme yapma ve değer yaratma olduğunda, basitlik her zaman en iyi yoldur. Doğrudan SQL, basit API’ler ve Linux’un temel araçları, çoğu yan proje için fazlasıyla yeterlidir. Önemli olan, projenin gerçek ihtiyaçlarını anlamak ve bu ihtiyaçlara uygun, en az karmaşıklıkta çözümler üretmektir. Bu yaklaşım, hem projenizi daha hızlı tamamlamanıza yardımcı olur hem de sizin kişisel motivasyonunuzu yüksek tutar.
Net pozisyonum şu yönde: Yan projeler, kurumsal dünyanın getirdiği alışkanlıkları sorgulama ve basitliğin gücünü yeniden keşfetme fırsatıdır. Bir sonraki yan projeme başlarken, ilk işim “gerçekten bu kadar karmaşık bir veri akışına ihtiyacım var mı?” sorusunu kendime sormak olacak.