Aristocrat — kapalı B2B iş kulübü ve yönetim paneli
Bakü'de yalnızca davetiyeyle üye kabul eden bir iş kulübü için üyelik sitesi. Next.js ile full-stack geliştirildi: çok adımlı başvuru akışı, etkinlik takvimi ve kulübün kendisinin yönettiği yönetim paneli — etkinlikler, haberler ve gelen başvurular için. Veritabanı bilinçli olarak kurulmadı; tüm veri sunucudaki JSON dosyalarında yaşıyor.
Canlı siteyi gör- Müşteri
- Aristocrat Social & Business Club — kapalı B2B ağı, Bakü
- Rol
- Full-stack geliştirme — sayfa mimarisi, çok adımlı form mantığı, Next.js route handler'ları, JSON tabanlı içerik katmanı, JWT ile korunan yönetim paneli, bileşen sistemi, animasyonlar ve VPS'te yayına alma (PM2 + Nginx).
- Stack
- Next.js · TypeScript · JWT Auth · JSON Storage · Tailwind CSS
- Tarih
- Ağustos 2026
- Dil
- 3 — AZ / EN / RU
Davetiyeyle çalışan bir kulübün sitesi aynı anda birbiriyle çelişen iki işi yapmalıdır: kulübü tanıtmalı, ama herkesi davet etmemelidir. Büyük bir «kayıt ol» düğmesi seçkinlik iddiasını daha ilk ekranda bozar; başvuru yolu olmayan bir site ise işlevsiz kalır. İkinci sorun site yayına çıktıktan sonra başlar. Etkinlik takvimi kulübün canlı olduğunun tek görünür kanıtıdır — geçmiş tarihlerle dolu bir takvim ise tam tersi mesaj verir. Başvurular da öyle: kulübün tüm üye akışı o formdan geçer ve bir posta kutusunda kaybolmamalıdır. Yani site yalnızca kurulmamalı, kulübün kendisi tarafından da sürdürülebilir olmalıydı.
- Çok adımlı başvuru formu — sorular tek tek, ilerleme göstergesiyle
- 2026 yıllık etkinlik takvimi, tarih ve mekân detayları
- Hedef kitle segmentleri: girişimciler, startup'lar, üst düzey yöneticiler
- Ayrıcalıklar bölümü: kapalı ağ, özel etkinlikler, yatırım fırsatları, bilgi paylaşımı
- Partnerler bölümü
- Kulübün felsefesini anlatan editoryal tarzda bölümler
- Ayrı etkinlikler sayfası — yaklaşan etkinlikler tarih ve kategoriyle (Kapalı Zirve, Gayriresmî Buluşma, Gala)
- Ayrı haberler sayfası
- Üyelik iki kola ayrıldı: bireysel (Kişiler) ve kurumsal (Şirketler)
- Yönetim paneli: etkinlik ekleme, düzenleme ve silme — tarih, mekân ve kategoriyle
- Yönetim panelinden haber yazılarının yayımlanması
- Başvuru formundan gelen yanıtların panel içinde listelenmesi
- Etkinlik ve haber görsellerinin doğrudan panelden yüklenmesi
- JWT ile korunan yönetici girişi — panel rotaları middleware seviyesinde kapalı
- Frontend
- Next.js App Router. Ana sayfa, üyelik kolları, etkinlikler, haberler ve başvuru sayfaları. Arayüz üç dilde ve seçim tarayıcıda saklanıyor — her dilin ayrı bir adresi yok; bu taviz aşağıda ayrıca açıklanıyor.
- Backend
- Ayrı bir API sunucusu yok — backend aynı Next.js uygulamasının route handler'larıdır: başvuruların alınması, etkinlik ve haberlerin yazılması, görsellerin yüklenmesi. Yönetim paneli de aynı projenin `/admin` rotalarında; yani tip tanımları, bileşenler ve yayına alma süreci siteyle ortak.
- Veri katmanı
- Veritabanı yok. Etkinlikler, haberler ve gelen başvurular sunucunun diskinde JSON dosyaları olarak saklanıyor: yönetim paneli dosyayı yazıyor, sayfalar okuyor. Nedeni aşağıdaki «Neden veritabanı kurulmadı?» kararında.
- Kimlik doğrulama
- Kendi JWT akışı: token sunucuda imzalanıp `httpOnly` cookie'ye yazılıyor. `/admin` altındaki rotalar hem middleware seviyesinde hem de her route handler'ın içinde kontrol ediliyor.
- Medya
- Etkinlik ve haber görselleri yönetim panelinden yükleniyor ve VPS'in diskine yazılıyor; sitede `next/image` üzerinden boyutlandırılarak sunuluyor.
- Altyapı
- VPS üzerinde Next.js süreci PM2 ile ayakta tutuluyor, önünde Nginx reverse proxy duruyor — SSL, sıkıştırma ve statik dosyaların önbelleği onun üzerinde.
Neden çok adımlı form?
Üyelik başvurusu çok sayıda soru gerektiriyor. Hepsini tek ekranda göstermek kullanıcıyı kaçırır. Formu adımlara böldüm ve ilerleme göstergesi ekledim — her ekranda tek soru olduğunda insan başladığı işi bitirmeye daha yatkın oluyor.
Tasarım hedef kitleyi süzer
Kulüp kitlesel değil. Görsel dil de bunu söylemeli: sakin renkler, geniş boşluklar, editoryal tipografi. Parlak ve neşeli bir tasarım burada mesajla çelişirdi — site, kimi davet ettiğini görünüşüyle de belli ediyor.
Statik üretimle anında açılış
Tanıtım sayfalarının içeriği sık değişmiyor, bu yüzden build sırasında hazır HTML olarak üretiliyorlar. Sonuçta sunucu beklemesi olmuyor — davetiyeyle gelen kişi siteyi anında açılmış görüyor. Etkinlik ve haber gibi değişen içerik ise sunucudan okunuyor.
Üyelik iki ayrı kola ayrıldı
Bir girişimcinin bireysel üyeliği ile bir şirketin kurumsal paketi aynı ürün değil — fiyat, ayrıcalıklar ve karar veren kişi farklı. Menüde bu iki yolu ayırmak, her iki alıcının da ilk tıklamada kendi sayfasına düşmesini sağlıyor. Tek bir «üyelik» sayfası ikisine de yarım cevap verirdi.
Etkinlikler sayfası vaat yerine takvim sunar
Kapalı bir kulüp hakkındaki en büyük şüphe «burada gerçekten bir şey oluyor mu» sorusudur. Tarihi ve kategorisi olan bir etkinlik listesi bu şüpheyi tek bakışta kapatıyor — cevabı metin değil, verinin kendisi veriyor. Bu, siteyi statik bir broşürden kulübün canlı vitrinine dönüştüren bölüm.
Arka planda Bakü silueti var, stok fotoğraf değil
Kulüp uluslararası bir ağ değil, belirli bir şehrin iş ortamı. Hero'da Bakü'nün tanınan silueti var — ziyaretçi ilk saniyede bu kulübün nerede ve kimlerin arasında kurulduğunu anlıyor. Nötr bir stok fotoğraf aynı yeri kaplar, ama hiçbir şey söylemezdi.
Neden veritabanı kurulmadı?
Kulübün tüm verisi bir avuç: yılda onlarca etkinlik, birkaç düzine haber, ayda birkaç başvuru. Bu hacimde ilişkisel bir veritabanı kurmak ayrı bir süreç, ayrı bir yedekleme düzeni ve migration disiplini demek — hiçbir gerçek fayda sağlamadan. Veri sunucudaki JSON dosyalarında saklanıyor: yönetim paneli dosyayı yazıyor, sayfa okuyor. Yedekleme bir klasörün kopyalanması, içeriğin geçmişi ise dosyaların kendisinde görünüyor. Bu «veritabanı kurmaya vakit olmadı» kararı değil — yüke uygun bir karar. Yazma sıklığı artıp aynı anda birkaç kişi düzenleme yapmaya başladığında veritabanı eklenmeli; ondan önce değil. Mühendislikte zor olan teknoloji eklemek değil, gerekmeyeni eklememe disiplinidir.
Takvim ancak güncel kaldıkça kanıttır
Yukarıda etkinlikler sayfasının kulübün canlı vitrini olduğunu yazmıştım — bu yalnızca takvim güncel kaldığında doğru. Geçmiş tarihlerle dolu bir sayfa kulübün çalıştığını değil, durduğunu gösterir. Bu yüzden etkinlikler kodda değil, yönetim panelinde yaşıyor: kulüp yeni tarihi benim katılımım olmadan kendisi ekliyor. Bu projede yönetim paneli ek bir özellik değil — sitenin ana argümanını ayakta tutan mekanizma.
Başvurular posta kutusuna değil, panele düşer
Üyelik başvurusu bu kulüp için en değerli veri. Yalnızca e-posta bildirimine dayanan bir form bir spam filtresiyle kaybolur ve en kötüsü, kimse kaybolduğunu bilmez. Bu yüzden her başvuru sunucuda saklanıyor ve yönetim panelinde liste olarak görünüyor — kulüp istediği zaman geri dönüp bakabiliyor.
Giriş token'ı httpOnly cookie'de saklanır
Panelde kulübün etkinlik planı ve başvuru yapan iş insanlarının kişisel bilgileri var — yani kapalılık iddiası olan bir kulüpte en hassas kısım tam olarak orası. Token `localStorage`'da saklansaydı, herhangi bir XSS açığı onu okuyabilirdi. `httpOnly` cookie JavaScript'e görünmez, `SameSite` ise token'ın başka bir siteden gelen isteğe eklenmesini engeller. Kontrol yalnızca middleware'de değil, her route handler'ın kendi içinde: arayüzü gizlemek koruma değil, sadece görüntüdür.
VPS, çünkü yazılan dosyalar kalıcı olmalı
Site kendi verisini sunucunun diskine yazıyor: JSON dosyaları ve yüklenen görseller. Serverless ortamda dosya sistemi geçicidir — panel bir şey yazar, bir sonraki deploy onu siler. Bu yüzden uygulama VPS'te çalışıyor: Next.js sürecini PM2 ayakta tutuyor, Nginx önde SSL'i ve statik dosyaları yönetiyor. JSON üzerinde çalışma kararı yalnızca kalıcı diski olan bir yerde anlamlı — bu ikisi ayrı seçimler değil, aynı seçim.
Üç dil tek adreste — taviz bilinçli olarak verildi
Arayüz üç dilde, ama her dilin ayrı bir adresi yok: seçim tarayıcıda saklanıyor. Bunun bedeli, arama motorlarının üç dili ayrı sayfalar olarak indekslememesi. Bu projede taviz kabul edilebilir, çünkü kulüp üyesi Google aramasından gelmiyor — davetiyeyle, doğrudan bağlantıdan geliyor. Organik arama bir kanal olsaydı, dil rota seviyesinde ayrılmalıydı; burada ise aynı iş kimseye hizmet etmeyen bir karmaşıklık olurdu.
Site Ağustos 2026'dan beri yayında. Kulüp etkinlik takvimini, haberleri ve gelen üyelik başvurularını yönetim panelinden kendisi yönetiyor — yani sitenin ana argümanı olan takvimin güncel kalması artık geliştiriciye bağlı değil. Mobil performans ölçüldü ve hedefin altında; optimizasyon planlanıyor, rakam iyileştiğinde buraya yazılacak.
- Kulüp etkinlik veya haber eklemek için bir geliştiriciye başvurmalı mı?
- Hayır. Etkinlikler, haberler ve görselleri yönetim panelinden yönetiliyor — kulüp takvimi kendisi güncelliyor, kod değişikliği gerekmiyor.
- Başvuru formundan gelen bilgiler nereye düşüyor?
- Her başvuru sunucuda saklanıyor ve yönetim panelinde liste olarak görünüyor, yani yalnızca e-posta bildirimine dayanmıyor. Kulüp istediği zaman geçmiş başvurulara dönebiliyor.
- Projede neden veritabanı yok?
- Kulübün veri hacmi küçük — yılda onlarca etkinlik ve haber, ayda birkaç başvuru. Bu yükte ilişkisel bir veritabanı ek fayda sağlamadan ayrı bir süreç ve yedekleme disiplini gerektirirdi. Veri sunucudaki JSON dosyalarında saklanıyor; yazma sıklığı arttığında veritabanına geçiş planlanmış bir adım, acil bir iş değil.
- Siteyi ve yönetim panelini kim geliştirdi?
- Tüm katmanlar — frontend, Next.js route handler'ları, içerik katmanı, yönetim paneli, kimlik doğrulama ve VPS'te yayına alma — Nurlan Qadirov tarafından yazıldı.
- Site kaç dilde çalışıyor?
- Arayüz üç dilde: Azerbaycan Türkçesi, İngilizce ve Rusça. Her dilin ayrı bir adresi yok — seçim tarayıcıda saklanıyor. Bu, kulübün kitlesi aramadan değil davetiyeden geldiği için bilinçli olarak verilmiş bir taviz.
Projenizi konuşalım — genellikle aynı gün yanıt veriyorum.
Nurlan Qadirov — Baku, Azerbaijan