· 2 dk okuma

Her bölümü düzenlenebilen bir tanıtım sitesi

yazan: · Proje: HARDWEY Web

#react #express #sqlite

HARDWEY, sanatçıların markalarından hisse satın almaya yarayan bir uygulama. Tanıtım sitesi sık sık değişiyor: SSS cevapları, kurucu biyografileri, partnerler, yasal sayfalar. Amaç, bu değişikliklerin hiçbirinin bir geliştirici ya da yeniden deploy gerektirmemesiydi.

Tek tablo, tek istek

İçerik modeli bilinçli olarak basit tutuldu. Her bölüm (hero, giriş, SSS, kurucular, partnerler, yasal sayfalar vb.) bir SQLite tablosunda tek bir satır: benzersiz bir bölüm adı, JSON olarak içerik ve bir database trigger'ı tarafından güncellenen bir zaman damgası. Kayıtlar upsert olarak yapılıyor, yani bir bölümü oluşturmak ile güncellemek aynı işlem.

Site yüklenirken her şeyi tek bir istekle çekiyor. Küçük bir React hook'u yanıtı beş dakika boyunca bellekte cache'liyor ve her component'e kendi bölümünü veriyor. Bir admin kaydettiğinde cache geçersiz kılınıyor ve hook'u kullanan her component veriyi yeniden çekiyor.

Ana sayfa hero'yu hemen yüklüyor, geri kalanını lazy-load ediyor. Böylece sayfanın ekrana gelmesi için tek bir içerik isteği ve küçük bir ilk bundle yetiyor.

Yapısı değişse de ayakta kalan içerik

Bölümlerin yapısı zamanla değişiyor. Bir alan listeye dönüşüyor, tek bir görsel birden fazla görsele dönüşüyor. Kayıtlı veriyi migrate etmek yerine, her bölümün client tarafında, kayıtlı olan her şeyi güncel yapıya zorlayan bir normalizer'ı var:

  • Eski alanları yeni yapılarına taşıyor.
  • Eksik ID'leri üretiyor.
  • Layout'un sabit sayıda eleman beklediği listeleri tamamlıyor.

Her component'in ayrıca varsayılan içeriği var; böylece eksik ya da boş bir bölüm bozuk bir sayfa yerine placeholder içeriğe düşüyor.

Admin uygulaması

Admin uygulaması aynı Vite bundle'ı içinde geliyor ama kendi route'unun arkasında lazy-load ediliyor, yani ziyaretçiler onu hiç indirmiyor. Her bölümün kendine ait bir editörü var; formların kapsamadığı durumlar için "Advanced JSON" modu ham içeriği düzenlemeye izin veriyor. Geçersiz JSON kaydedilmeden önce reddediliyor. Bir bölüm henüz yoksa editör onun şablonundan başlıyor, böylece yeni bölümler admin uygulamasından oluşturulabiliyor.

Görseller API üzerinden, tür kontrolü ve boyut sınırıyla (varsayılan olarak 5 MB) yükleniyor. Rastgele dosya adlarıyla kaydediliyor ve bir ad asla tekrar kullanılmadığı için uzun ömürlü cache header'larıyla sunuluyor.

Editörü kilitli tutmak

Admin erişimi kısa ömürlü access token'lar ve daha uzun ömürlü refresh token'lar kullanıyor. İkisi de SameSite=strict ile httpOnly cookie'lerde tutuluyor; böylece sayfa script'leri bunları okuyamıyor, başka siteler de gönderemiyor. Her yazma işlemi ayrıca API'den alınıp bir header içinde gönderilen bir CSRF token'ı gerektiriyor. Parolalar bcrypt ile hash'leniyor, girişlere rate limit uygulanıyor ve ilk admin hesabı ortamda açıkça tanımlanmış bir parola olmadan oluşturulamıyor.

Hosting tuhaflıkları

Sunucu hem shared hosting'de Passenger arkasında hem de tek başına çalışacak şekilde yazıldı. Bu tür bir proxy'nin arkasında istekler /api önekiyle ya da öneksiz gelebiliyor; bu yüzden sunucu, proxy yapılandırmasına bağlı kalmak yerine aynı route'ları iki yolun altına da bağlıyor. Kendi listener'ını yalnızca Passenger altında çalışmıyorsa başlatıyor. SQLite write-ahead log modunda çalışıyor; bu da bir admin kaydederken sitenin içeriği okumaya devam etmesini sağlıyor.

Kaynak kod GitHub'da.