Üç bileşen, tek sözleşme.
Thundrly; landing, Chrome eklentisi ve FastAPI backend olmak üzere üç bağımsız bileşenden oluşur. Hepsi aynı AnalyzeRequest / AnalyzeResponse sözleşmesi etrafında konuşur. Aşağıda her katmanın görevi, veri akışı, dayanıklılık katmanları, veritabanı şeması ve dağıtım topolojisi net olarak anlatılıyor.
- 11 bölüm
- 8 adımlı zaman çizelgesi
- 4 paralel ajan + 1 karar
Üç katman, paylaşılan tip sözleşmesi.
Landing ve eklenti hem AnalyzeRequest'i üretir hem de AnalyzeResponse'u tüketir; backend bu sözleşmenin tek sahibidir.
Tanıtım sayfası ve canlı demo. Backend ulaşılamazsa fixture fallback ile çalışır.
- Canlı backend bağlantısı (SSE stream)
- Framer Motion + Tailwind
- Statik SSR build (standalone)
Sepete Ekle tıklamalarını yakalar, ürün payload'ı oluşturur, paneli render eder.
- Capture-phase tıklama yakalama
- 5 katmanlı productExtractor
- Shadow DOM izole panel (React)
5 ajanı paralel çalıştıran orkestratör; karar ağırlıklı toplam + eskalasyon kuralı.
- 4 paralel sinyal ajanı + karar ajanı
- TTL+LRU cache, retry + circuit breaker
- SQLAlchemy + Alembic (pgvector planlı)
Her katmanın iç modülleri.
Repo bağımsız üç klasör halinde organize: landing/, extension/, backend/ — paylaşılan tipler shared/ altında.
- app/Next.js App Router; / ve /mimari
- components/sections/Hero, Demo, Mimari, Footer
- components/demo/AgentFlow, ExtensionPanelMock, ProductPageMock
- lib/runDemo.tsOffline fallback akış simülatörü
- lib/streamAnalyze.tsBackend SSE bağlantısı
- shared/demo/Backend yokken kullanılan fixture'lar
- manifest.jsonMV3 izinleri, contentScript glob'ları
- src/contentScript.tsCapture-phase click yakalama
- src/utils/productExtractor.ts5 katmanlı çıkarım: JSON-LD → og: → DOM
- src/utils/platformSelectors.tsTrendyol / Hepsiburada / N11 seçici paketleri
- src/background.tsService worker; backend HTTP isteği
- src/panel/mount.tsxShadow DOM içine React mount
- src/panel/App.tsxKarar paneli, agent chips
- src/api/client.tsDemo fallback fixture'ı
- app/main.pyFastAPI app + lifecycle hooks
- app/api/REST + SSE rotaları, admin guard
- app/services/graph.pyLangGraph StateGraph: 4 paralel + decision
- app/services/orchestrator.pySenkron fallback orkestratör
- app/agents/review_agent.pyGemini + heuristik tekrar tespiti
- app/agents/price_agent.py30/90 günlük geçmiş + dış kaynak
- app/agents/budget_agent.pyAylık + kategori limitleri
- app/agents/impulse_agent.pySayfa süresi + tıklama hızı
- app/agents/decision_agent.pyAğırlıklı toplam + Gemini özet
- app/core/cache.pyTTL + LRU + telemetri
- app/core/_gemini_resilience.pyRetry + circuit breaker
- app/db/models.pyPriceObservation, UserBudgetRow
Sepete Ekle'den karara, 8 adım.
Her adım için ölçülen ortalama gecikme ve ilgili kod satırı. Toplam yol: ~3.2 saniye.
- 01
Yakalama
T+0msEklenti `contentScript` capture-phase listener'ı Trendyol/Hepsiburada/N11 sayfasında "Sepete Ekle" tıklamasını yakalar.
event.preventDefault(); event.stopImmediatePropagation(); - 02
Ürün Çıkarımı
T+12ms5 katmanlı productExtractor sırasıyla JSON-LD, og:* meta, platforma özel DOM seçicileri ve fallback'leri dener.
extract(): JSON-LD ▸ og: ▸ DOM ▸ data-kg-* ▸ fallback - 03
Panel Mount
T+45msShadow DOM içine React panel mount edilir. Host sayfanın CSS'i panele dokunmaz.
attachShadow({ mode: "closed" }) - 04
HTTP İstek
T+120msbackground.ts service worker AnalyzeRequest'i POST eder.
POST /api/analyze-purchase (SSE upgrade) - 05
Paralel Ajanlar
T+260msLangGraph orchestrator 4 sinyal ajanını paralel başlatır; her biri 0–100 risk + gerekçe döner.
review · price · budget · impulse → Promise.allSettled - 06
Karar
T+3100msdecision_agent ağırlıklı toplam + eskalasyon uygular, Gemini ile özet üretir.
risk = 0.30·p + 0.25·r + 0.25·b + 0.20·i - 07
Panel Sonuç
T+3200msPanel kararı (renk, özet, 3 gerekçe) gösterir. Kullanıcı eylemi seçer.
response.decision ∈ { green, yellow, red } - 08
Aksiyon
T+3200ms+Devam Et → data-kg-bypass=1 ile orijinal click replay; 30 sn düşün / kapat → satın alma iptal.
btn.setAttribute('data-kg-bypass','1'); btn.click();
LangGraph: dört paralel sinyal, tek karar.
Sinyal ajanları birbirinden bağımsız; karar ajanı fan-in node olarak çalışır, ağırlıklı toplamı ve eskalasyon kurallarını uygular.
Ağırlıklı toplam + eskalasyon.
Risk skoru 0–100 arası; eşik bantları ve eskalasyon kuralı tek bir güçlü sinyalin kaybolmamasını sağlar.
Tek bir ajan çok güçlü sinyal veriyorsa ağırlıklı toplam düşük olsa bile karar yükseltilir — sinyal kaybolmasın diye.
- single_max ≥ 80 → risk en az 70 (kırmızı zorunlu)
- single_max ≥ 45 → risk en az 42 (sarı zorunlu)
Yorum Kitabı
risk 0Yorumlar organik, fiyat tutarlı, bütçede bol yer var.
Kablosuz Kulaklık
risk 0Fiyat son 90 günde 2 kez yükselip indirilmiş; yorumlarda burst.
Oversize Hoodie
risk 0Yapay indirim, jenerik yorum kümeleri, kategori limiti aşılıyor.
TTL kademesi + devre kesici.
Gemini gibi dış servisler ne yavaşlatır, ne de düşürür: her sinyal tipi için ayrı TTL, retry/jitter, circuit breaker ve hedefli invalidation.
PostgreSQL şeması + pgvector.
Mevcut: PriceObservation, UserBudgetRow. Planlı: analyses log tablosu, review_vectors (pgvector).
İzolasyon, doğrulama, minimum veri.
Eklenti her sayfada çalışan en agresif yüzey; izolasyon ve sıkı doğrulama ön planda.
Docker Compose, nginx önünde.
Üç container + host nginx; her servis 127.0.0.1'e bind olduğu için public yüzey sadece nginx'in açtığı kadar.
Üç klasör, paylaşılan tipler.
pnpm / Turbo gibi monorepo aracı yok — hackathon ölçeğinde ekstra yüzey alanı yaratmamak için.
- Next.js15
- React18
- Tailwind CSS3.4
- Framer Motion11
- TypeScript5.6
- ManifestV3
- Vite + React—
- Shadow DOM panel—
- chrome.runtime—
- FastAPI—
- Pydanticv2
- LangGraph—
- Google Gemini2.5 Flash
- SQLAlchemy + Alembic—
- PostgreSQL16
- pgvector (planlı)—
- TTL + LRU cache—
- Docker Compose—
Neden böyle kurduk.
Eklenti paneli host sayfanın CSS'inden tamamen izole; hiçbir e-ticaret stilinden etkilenmez.
Gemini 2.5 Flash retry + circuit breaker arkasında çalışır; servis düşerse heuristik fallback devreye girer ve karar yine üretilir.
AnalyzeRequest / AnalyzeResponse shared/types ile TypeScript ve Pydantic'te aynalanır.