insanlarin farkli eticaret sitelerinden urunler ekleyip bunlarin fiyat takibini yapabilecegi, listeler ekleyebilecegi, urunleri listeye kayit eebilcegi, birbirini takip ederek listelerini goruntuleyebilecegi bir mobil uygulama fikrim var. uygulamayi tasarladim sirada backend var. backend olarak laravel kullanacagim ancak olceklendirme icin elasticsearch ve redis de kullanmayi dusunuyorum. backendin fiyat takibi ise su sekilde olacak. product.platform_id ile gordugun uzere hangi site uzerinden kayit ettigini tutacagim. burada hazir service ve procedurlerim olacak. ornegin trendyol fiyatlari ty-plus-price-discounted-price / discounted/ price icerisinde tutuyor. urun girildigi an verilen url icerisine webscrabbing ile girilerek bi divlerin ici kontrol edilerek guncel fiyat sklaasi tutulacak ve bu islemler job seklinde periyodik calisacak. diger siteler icin de belli protokoller olacak kontrol icin. bu gibi islemler best practice mimari cikartmani istiyorum. ihtiyacim olan server gereksinimlerini , kurulumlarini analtan detayli bir kilavuz cikart. ornegin uygulamada 10000den fazla urun olabilir bunun icin elastic search veya her seferinde anasayfanin apisine cikmamasi icin redis ile cacheleme yapmaliyim. asagida planladigim db semasi var bunu incele ve bana uygun, gelistirilerebilir , olceklendirilebilir yapiyi oluistur. ayrica suan bildirim arayuzum var ancak db planlanmadi. bunu da ver en son . // Use DBML to define your database structure
// Docs: https://dbml.dbdiagram.io/docs

Table userfollows {
  following_user_id integer
  followed_user_id integer
  created_at timestamp
}
Table listFollow {
  list_id integer
  user_id integer
  created_at timestamp
}

Table users {
  id integer [primary key]
  name varchar
  surname varhcar
  username varchar
  role varchar
  password varchar
  image_url text
  created_at timestamp
  updated_at timestamp
}

Table products {
  id integer [primary key]
  title varchar
  price float
  discount_price float
  created_user_id integer [not null]
  status varchar
  platform_id integer
  url text
  category_id integer
  created_at timestamp
  is_other_visible boolean
}

Table priceHistory{
  id integer [primary key]
  product_id integer
  price float
  created_at timestamp
  updated_at timestamp
}

Table platforms {
  id integer [primary key]
  title varchar
  slug varchar
  created_at timestamp
  updated_at timestamp
}
Table categories {
  id integer [primary key]
  title varchar
  created_at timestamp
  updated_at timestamp
}
Table priceAlarms{
  id integer [primary key]
  user_id integer
  product_id integer
  price float
  created_at timestamp
  updated_at timestamp
}
Table lists{
  id integer [primary key]
  user_id integer
  title varchar
  image_url text
  created_at timestamp
  updated_at timestamp
}
Table lists_products{
  id integer [primary key]
  product_id integer
  list_id integer
  created_at timestamp
  updated_at timestamp
}

Ref user_products: products.created_user_id > users.id // many-to-one

Ref: users.id < userfollows.following_user_id

Ref: users.id < userfollows.followed_user_id
Ref price_log: products.id > priceHistory.id // many-to-one
Ref: categories.id < products.category_id
Ref: platforms.id < products.platform_id
Ref: users.id < priceAlarms.user_id
Ref: products.id < priceAlarms.product_id
Ref: products.id < lists_products.product_id
Ref: lists.id < lists_products.list_id
Ref: lists.id < listFollow.list_id
Ref: users.id < listFollow.user_id

✅ 1) Önerilen Yüksek Seviye Mimari (Best Practice)
📌 Genel Mimari (Component View)
Mobile App
   |
   v
API Gateway (Laravel)
   |
   |-- mysql (Ana DB)
   |-- Redis (Cache + Queue)
   |-- Elasticsearch (Search + Analytics)
   |-- Job Workers (Laravel Horizon / Supervisor)
   |-- Scraper Service (Node.js / Python veya Laravel)
   |-- Scheduler (Laravel Scheduler + Cron)
   |-- Notification Service (Laravel + Pusher/FCM)

Neden bu yapı?

Laravel → İş mantığı, API, auth, permission, job orchestration

mysql → İlişkisel veri (kullanıcı, ürün, listeler, fiyat geçmişi vb.)

Redis →

API cache (ana sayfa, ürün listeleri, kullanıcı listeleri)

Queue backend (fiyat takip job’ları)

Elasticsearch →

Ürün arama

Filtreleme (platform, kategori, fiyat aralığı)

Büyük ölçekli veri okuma performansı

Worker’lar → Web scraping + fiyat takibi paralel çalışır

Scheduler → Periyodik job tetikleme

✅ 2) Fiyat Takibi (Scraping) için Job Mimarisi
A) Ürün eklenirken akış

Kullanıcı ürünü URL ile ekler

Laravel API → ProductCreated event fırlatır

FetchProductInitialPriceJob queue’ya girer

Worker:

Platform’a göre uygun Scraper Strategy seçer

Web scraping yapar

İlk fiyatı kaydeder (products.price)

price_history tablosuna ilk kayıt atar

Strategy Pattern (Best Practice)
interface PriceScraperInterface {
   public function fetchPrice(string $url): float;
}

class TrendyolScraper implements PriceScraperInterface {
   public function fetchPrice(string $url): float {
      // ty-plus-price-discounted-price div'ini parse et
   }
}

class ScraperFactory {
   public static function make(int $platformId): PriceScraperInterface {
      return match($platformId) {
         1 => new TrendyolScraper(),
         2 => new HepsiburadaScraper(),
         3 => new AmazonScraper(),
         default => throw new Exception("Unsupported platform")
      };
   }
}

B) Periyodik Fiyat Takibi (Scheduler + Jobs)
Laravel Scheduler (Her 10-30 dk)
$schedule->job(new CheckProductPricesJob)->everyThirtyMinutes();

CheckProductPricesJob (Dispatcher)

Tüm ürünleri almaz

Chunking + Cursor ile iterasyon yapar

Product::where('status','active')
   ->cursor()
   ->each(fn($product) => CheckSingleProductPriceJob::dispatch($product));

CheckSingleProductPriceJob

Platform’a göre scraper seç

Yeni fiyatı çek

Eğer fiyat değiştiyse:

products.price güncelle

price_history tablosuna yeni kayıt ekle

Fiyat alarmı olan kullanıcıları bul

Notification job’u tetikle

✅ 3) Redis Kullanımı (Cache + Queue)
A) API Cache Stratejisi
Ana Sayfa (ürün listesi)

Cache key:

home:products:page:{page}:sort:{sort}:category:{category}


Örnek:

$products = Cache::remember(
   "home:products:page:$page:sort:$sort",
   300,
   fn() => Product::with('platform','category')
                  ->orderBy($sort)
                  ->paginate(20)
);

B) Redis Queue (Horizon önerilir)

config/queue.php

'default' => 'redis',


Horizon kurulumu:

composer require laravel/horizon
php artisan horizon:install
php artisan migrate

✅ 4) Elasticsearch Kullanımı (Search + Analytics)
A) Hangi datalar ES’e gider?

products

platforms.title

categories.title

price

discount_price

created_at

B) Laravel Scout + Elasticsearch
composer require laravel/scout
composer require babenkoivan/scout-elasticsearch-driver


Product model:

class Product extends Model {
   use Searchable;

   public function toSearchableArray() {
      return [
         'id' => $this->id,
         'title' => $this->title,
         'price' => $this->price,
         'platform' => $this->platform->title,
         'category' => $this->category->title,
      ];
   }
}


Arama:

Product::search($query)->paginate(20);

✅ 5) Sunucu Gereksinimleri (10000+ ürün için)
Minimum (Başlangıç)
Bileşen	Önerilen
App Server	4 vCPU, 8GB RAM
mysql	4 vCPU, 8GB RAM, 100GB SSD
Redis	2 vCPU, 4GB RAM
Elasticsearch	4 vCPU, 8GB RAM
Worker Server	4 vCPU, 8GB RAM
Scale ettiğinde (100.000+ ürün)

App → Kubernetes / Docker Swarm

DB → Read Replica ekle

Redis → Cluster mode

Elasticsearch → 3 node cluster

✅ 6) Veritabanı Şeman için İyileştirmeler
🔧 Sorunlar ve düzeltmeler
❌ priceHistory relation yanlış

Şu satır hatalı:

Ref price_log: products.id > priceHistory.id


✅ Doğrusu:

Ref: products.id < priceHistory.product_id

🔧 products tablosu için öneriler

Eklenmesini öneririm:

Table products {
  id integer [primary key]
  title varchar
  price decimal(10,2)
  discount_price decimal(10,2)
  created_user_id integer
  status varchar
  platform_id integer
  url text
  category_id integer
  is_other_visible boolean
  last_checked_at timestamp
  created_at timestamp
}

🔧 priceHistory iyileştirme
Table priceHistory {
  id integer [primary key]
  product_id integer
  price decimal(10,2)
  checked_at timestamp
}

✅ 7) Bildirim (Notification) DB Tasarımı
🔔 Bildirimler Tablosu
Table notifications {
  id integer [primary key]
  user_id integer
  type varchar   // price_drop, price_rise, new_follower, list_shared
  data json
  is_read boolean
  created_at timestamp
}

🔔 Fiyat Alarmı Bildirimi Örneği (data)
{
  "product_id": 123,
  "old_price": 1500,
  "new_price": 1200
}

🔔 Kullanıcı Push Token’ları
Table user_devices {
  id integer [primary key]
  user_id integer
  device_token text
  platform varchar  // ios, android
  created_at timestamp
}

✅ 8) Son Mimari Özeti (Ölçeklenebilir)
Katman	Teknoloji
API	Laravel
DB	mysql
Cache	Redis
Queue	Redis + Horizon
Search	Elasticsearch
Scraping	Laravel Jobs (veya ayrı Node.js microservice)
Scheduler	Laravel Cron
Bildirim	Laravel + FCM / Pusher