Monaf Horany
Tüm çalışmalar

003

2024 — 2025

Netlastik

Bayiler için B2B lastik ticaret uygulaması; App Store ve Google Play'de yayında.

yayınlandığı yer
iOS + Android
uygulama mağazası, ikisi de yayında
2
özellik modülü
17

Mimari

Netlastik — bayi uygulaması ve ödeme akışıBayi Flutter uygulamasını açıp hangi hesap adına alışveriş yaptığını seçiyor; bu seçim katalogu, fiyatlandırmayı ve cari hesabı tüm oturum boyunca kapsıyor. Uygulama, paylaşılan tek bir dio istemcisi üzerinden tek bir HTTP API ile konuşuyor; bu API hem lastik katalogunu hem de bayinin cari hesabını sunuyor. Ödeme ise uygulamadan tamamen çıkıyor: kart girişi bankanın kendi webview’ında yapılıyor ve sipariş yalnızca sonuç geri döndüğünde kapanıyor.1 · account scope2 · pay3 · settledFlutter appiOS · AndroidNetlastik APIHTTP · dioCataloguetyres · pricingCari hesapledger · receiptsBank webviewcard entry
Bayi Flutter uygulamasını açıp hangi hesap adına alışveriş yaptığını seçiyor; bu seçim katalogu, fiyatlandırmayı ve cari hesabı tüm oturum boyunca kapsıyor. Uygulama, paylaşılan tek bir dio istemcisi üzerinden tek bir HTTP API ile konuşuyor; bu API hem lastik katalogunu hem de bayinin cari hesabını sunuyor. Ödeme ise uygulamadan tamamen çıkıyor: kart girişi bankanın kendi webview’ında yapılıyor ve sipariş yalnızca sonuç geri döndüğünde kapanıyor.
  • İstemci
  • Servis
  • Veri deposu
  • Harici

Problem

Netlastik, sürücülere değil bayilere satan bir lastik tedarikçisi. Uygulama her iki mağazada da müşterinin kendi geliştirici hesapları altında yayınlanıyor ve mevcut katalogları ile muhasebeleri için bayiye dönük yüzey olarak kuruldu.

Bayiler tüketiciler gibi alışveriş yapmaz. Çoğu zaman tek kişi birden fazla hesap adına alım yapar, fiyatlar hangi hesap adına hareket ettiğine göre değişir ve en sık baktıkları şey sipariş geçmişi değil cari bakiyedir: ne borçlu olduğu, ne ödediği ve bunu kanıtlayan dekont. Tüketici mağazası kalıbı bunların hiçbiriyle temas ettiğinde ayakta kalmıyor.

Yaklaşım

Tek bir paylaşılan çekirdek üzerine on yedi özellik modülü olarak kurulmuş bir Flutter istemcisi: durum için Bloc, bağımlılıklar için get_it, gezinme için go_router ve her modülün üzerinden geçtiği tek bir dio istemcisi. Bayinin seçtiği hesap, sonrasındaki her şeyi kapsayan oturum durumu; böylece hiçbir ekranın ona göre filtrelemeyi hatırlaması gerekmiyor. Ödeme ise yeniden yazılmak yerine bankanın kendi webview'ına devrediliyor, dolayısıyla kart bilgisi uygulamaya hiç ulaşmıyor.

Fark yaratan kararlar

  1. 01

    Tek mimari, on yedi kez tekrarlanmış

    Tek mimari, tekrar tekrar. Her özellik modülü aynı şekle sahip: durum için Bloc, kurulum için get_it, giriş için go_router, taşıma için dio. On yedi modül, "bir ekranı nasıl kurarım" sorusunun tek bir cevabı olmasını zorunlu kılacak kadar çok; aksi hâlde kod tabanı on yedi ayrı lehçeye dönüşür.

  2. 02

    Hatalar istisna değil, değerdir

    Hatalar istisna değil, değerdir. İstekler dartz'ın Either tipini döndürüyor; yani başarısızlık, arayüze ulaşmadan önce çağıranın açmak zorunda olduğu bir şey. Unutulan bir try/catch sessizce başarısız olur; ele alınmamış bir Either ise derlenmez.

  3. 03

    Seçili hesap oturum durumudur

    Seçili hesap bir parametre değil, oturum durumu. Birden çok hesap adına hareket eden bayi birini seçiyor ve bu seçim katalogu, fiyatlandırmayı ve cari hesabı tüm oturum boyunca kapsıyor. Hesap kimliğini her çağrıda elden ele taşımak ise er ya da geç yanlış bakiye gösteren bir ekran yayınlayan yaklaşım.

  4. 04

    Cari hesap birinci sınıf bir yüzeydir

    Cari hesap birinci sınıf bir yüzey. Bakiye hareketleri, dekontlar, başarılı ve başarısız ödemeler sipariş geçmişine gömülmek yerine kendi ekranlarını alıyor — çünkü bayinin her gün açtığı ekran katalog değil, cari hesap.

  5. 05

    Kart girişi uygulamada hiç yapılmaz

    3-D Secure akışı, benim yazdığım bir kart formunda değil bankanın kendi webview'ında çalışıyor. Kart bilgisi uygulamanın sürecine hiç girmiyor; yani istemci onu ne saklıyor, ne iletiyor, ne de işliyor — bir ödeme entegrasyonunun en ağır uyumluluk yükünü taşıyan kısmı burada hiç yok ve doğru yapılması en zor olacak akış, yazmadığım akış oldu. Bedeli, sonucun eşzamansız gelmesi; aşağıdaki üç dönüş yolunu varsayımsal değil gerçek bir probleme dönüştüren de bu.

Zor problemler

  1. 01

    Fiyat, soranın kim olduğunun bir fonksiyonudur

    B2B fiyatlandırma hesaba özel, dolayısıyla hiçbir ürünün "asıl" fiyatı önbelleğe alınamıyor. Her fiyat, soranın kim olduğunun bir fonksiyonu; bu da akla ilk gelen katalog önbellekleme yöntemlerinin çoğunu eliyor ve hesap değişimini bir önbellek sınırına dönüştürüyor.

  2. 02

    Bir ödeme üç şekilde dönebilir

    Uygulamadan çıkan bir ödeme üç şekilde dönebilir: kapanmış, reddedilmiş ya da bayi webview’ı akışın ortasında kapattığında hiç dönmemiş. Bu yüzden başarı ve başarısızlık kendi durumlarına sahip ayrı ekranlar ve yarıda bırakılan bir ödeme sessizce başarı olarak okunmuyor.

  3. 03

    İki mağaza, tek dal

    İki mağaza, iki inceleme süreci, tek kod tabanı. iOS ve Android izinlerde, webview davranışında ve sürüm temposunda ayrışıyor; ikisinin de aynı daldan yayınlanabilir kalması gerekiyordu.

Rolüm

İstemcinin tek mühendisi. Mimari, durum yönetimi, gezinme, on yedi özellik modülünün tamamı, ödeme devri ve her iki mağaza sürümü.

Durum

Google Play ve App Store'da yayında. 2024–2025 arasında geliştirilip yayınlandı; sonrasında devredildi ve bakımını başkaları sürdürüyor.

Teknolojiler

Mobil
FlutterDartBloc / Cubitgo_routerget_itdio
Veri
dartzequatableshared_preferences
Ön uç
flutter_screenutilflutter_svgcached_network_imageinfinite_scroll_paginationpinputwebview_flutter