feat: tek birleştirilmiş JSON yapısına geçiş + sosyal kanıt fallback

Ne yaptık:
- data_consolidator.py: Tüm normalizasyon ve hesaplama mantığını main.py'den çıkardık
- Dashboard endpoint 1150 satırdan 25 satıra düştü (main.py -1730/+1880 net)
- Enrichment bitince otomatik konsolide dosya oluşturuluyor (report_{id}_data.json)
- Eski raporlar ilk dashboard isteğinde lazy migration ile konsolide ediliyor
- Trendyol API artık order-count döndürmediği için baskets fallback eklendi
- Inline socialProofs (scrape) > enrichment API öncelik sırası uygulandı
- Frontend KPI başlıkları orders/baskets durumuna göre dinamik değişiyor
- logging_config.py, category_seeder.py, alembic migration eklendi
- Playwright ile 9 tab test edildi, tüm veriler doğru

Neden yaptık:
- 3 farklı kaynaktan her istekte birleştirme yapılması veri tutarsızlığına ve yavaşlığa yol açıyordu
- Tek konsolide JSON dosyası ile dashboard anında yükleniyor
- Trendyol API değişikliği nedeniyle sipariş verisi kayboluyordu, baskets fallback ile çözüldü

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
furkanyigit34
2026-03-28 22:25:25 +03:00
parent 187c59ec9b
commit ce1dc1e25f
15 changed files with 1878 additions and 1459 deletions

137
CLAUDE.md
View File

@@ -1,12 +1,12 @@
# CLAUDE.md
Bu dosya Claude Code (claude.ai/code) için proje rehberidir.
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Proje Özeti
**Trendyol Product Dashboard**: Trendyol e-ticaret platformu için kategori bazlı ürün analiz sistemi. 7 tab'lı dashboard, otomatik rapor oluşturma ve sosyal kanıt metrikleri.
**Trendyol Product Dashboard**: Trendyol e-ticaret platformu için kategori bazlı ürün analiz sistemi. 9 tab'lı dashboard, otomatik rapor oluşturma, sosyal kanıt metrikleri ve hidden champion analizi.
**Stack**: FastAPI + React 19 + Vite + SQLite + Tailwind CSS
**Stack**: FastAPI + React 19 + Vite + PostgreSQL + Tailwind CSS
## Geliştirme Komutları
@@ -15,17 +15,33 @@ Bu dosya Claude Code (claude.ai/code) için proje rehberidir.
python3 start.py
# Manuel başlatma (iki terminal)
cd backend && python3 main.py # Terminal 1 - Backend
cd admin-panel && npm run dev # Terminal 2 - Frontend
cd backend && python3 main.py # Terminal 1 - Backend (port 8001)
cd admin-panel && npm run dev # Terminal 2 - Frontend (port 5173)
# Dependency kurulumu
cd backend && pip install -r requirements.txt # Python
cd admin-panel && npm install # Node.js
# Diğer komutlar
cd admin-panel && npm run build # Frontend build
cd admin-panel && npm run lint # Lint
cd backend && python3 -c "from database import init_db; init_db()" # DB init
# Build & lint
cd admin-panel && npm run build # Frontend production build
cd admin-panel && npm run lint # ESLint
# Backend testler
cd backend && pytest # Tüm testler
cd backend && pytest tests/test_cache.py # Tek test dosyası
cd backend && pytest tests/test_cache.py -k "test_ttl" # Tek test
# Frontend E2E testler (Playwright)
cd admin-panel && npx playwright test # Tüm E2E testler
cd admin-panel && npx playwright test tests/rare-keywords.spec.js # Tek spec
# Docker ile çalıştırma
./build-docker.sh && ./start-docker.sh # Build + start
./stop-docker.sh # Durdur
# DB migration
cd backend && alembic upgrade head # Migration uygula
cd backend && alembic revision --autogenerate -m "description" # Yeni migration
```
**Erişim URL'leri**:
@@ -39,23 +55,36 @@ cd backend && python3 -c "from database import init_db; init_db()" # DB init
### 3 Katmanlı Yapı
```
React Frontend (admin-panel/) → FastAPI Backend (backend/) → SQLite + JSON
├── CategoryManagement.jsx ├── main.py (~4400 satır) ├── trendyol.db
├── ReportGeneration.jsx ├── database.py ├── categories/*.json
├── ReportList.jsx ── scraper.py └── reports/*.json
── ReportDashboard.jsx (7 tab)
React Frontend (admin-panel/) → FastAPI Backend (backend/) PostgreSQL + JSON
├── ReportDashboard.jsx (9 tab) ├── main.py (~5000 satır) ├── trendyol_db
├── ReportGeneration.jsx ├── database.py (ORM) ├── categories/*.json
├── ReportList.jsx ── scraper.py └── reports/*.json
── ReportComparison.jsx ├── google_trends_helper.py
└── CategoryManagement.jsx └── analytics/
├── metrics.py
└── champion_finder.py
```
### Dashboard Tab'ları (7 adet)
### Frontend Routes
| Path | Component | Açıklama |
|------|-----------|----------|
| `/` veya `/report` | ReportGeneration | Yeni rapor oluştur |
| `/reports` | ReportList | Kayıtlı raporlar |
| `/reports/:reportId` | ReportDashboard | 9 tab'lı analiz dashboard |
| `/compare` | ReportComparison | Yan yana rapor karşılaştırma |
### Dashboard Tab'ları (9 adet)
| Tab ID | Tab Adı | Component | Açıklama |
|--------|---------|-----------|----------|
| overview | Genel Bakış | OverviewTab | KPI'lar, özet grafikler |
| brand | Marka | BrandTab | Marka analizi, pazar payı |
| category | Kategori | CategoryTab | Kategori dağılımı |
| origin | Menşei | OriginTab | Ülke bazlı analiz |
| barcode | Barkod | BarcodeTab | Barkod veri analizi |
| keyword | Keyword Aracı | KeywordTab | Anahtar kelime analizi |
| barcode | Barkod | BarcodeTab | Barkod/GS1 menşei analizi |
| keyword | Keyword Aracı | KeywordTab | Anahtar kelime + Google Trends |
| product-finder | Ürün Bulma | ProductFinderTab | Ürün arama/filtreleme |
| hidden-champions | Gizli Şampiyonlar | HiddenChampionsTab | Düşük yorum, yüksek puan fırsatları |
| opportunity | Fırsat Analizi | OpportunityTab | Pazar fırsat analizi |
### Veri Akışı
@@ -77,12 +106,12 @@ React Frontend (admin-panel/) → FastAPI Backend (backend/) → SQLite +
**Backend'den gelen hazır objeleri kullan, ham hesaplama YAPMA:**
```jsx
// DOĞRU - Hazır veriyi kullan
// DOĞRU - Hazır veriyi kullan
const kpis = dashboardData?.kpis || {};
const topProducts = dashboardData?.charts?.top_products || [];
const topBrands = dashboardData?.charts?.top_brands || [];
// YANLIŞ - all_products'tan hesaplama yapma
// YANLIŞ - all_products'tan hesaplama yapma
const total = dashboardData?.all_products.reduce((sum, p) => sum + p.price, 0);
```
@@ -97,12 +126,11 @@ Frontend hesaplamalı veri, alan adı uyumsuzluğuna yol açabilir. Detay için:
**Çözüm Pattern - Mapping Layer**:
```jsx
// Veriyi component beklentilerine dönüştür
const transformed = sourceData.map(item => ({
country: item.name, // Beklenen alana map'le
name: item.name, // Orijinali koru
count: item.productCount, // Beklenen alana map'le
productCount: item.productCount // Orijinali koru
country: item.name,
name: item.name,
count: item.productCount,
productCount: item.productCount
}));
```
@@ -111,7 +139,7 @@ const transformed = sourceData.map(item => ({
1. Tab config'i `src/constants/tabGroups.js`'e ekle
2. Tab component'ini `src/components/dashboard-tabs/` altına oluştur
3. `ReportDashboard.jsx`'te import et ve render bloğu ekle
4. **Her zaman veri dönüşümü için console.log ekle**
4. Gerekiyorsa backend'e yeni endpoint ekle (`main.py`)
## API Entegrasyonu
@@ -123,15 +151,10 @@ const transformed = sourceData.map(item => ({
| ENRICHMENT | 120s | Sosyal kanıt zenginleştirme |
| KEYWORD_ANALYSIS | 300s | Keyword analizi |
### Polling Pattern
```jsx
// Exponential backoff with jitter (1s → 5s max)
import { fetchWithTimeout, API_BASE_URL } from '../config/api';
```
### Rate Limit
- Sosyal kanıt API: 2 istek/saniye
- Exponential backoff kullanılır (%75 istek azaltımı sağlandı)
### Rate Limit & Resilience
- Sosyal kanıt API: 2 istek/saniye (RateLimiter)
- Circuit breaker pattern for external API calls
- Exponential backoff with jitter (1s → 5s max)
## Kod Değişiklik Kuralları
@@ -141,18 +164,45 @@ import { fetchWithTimeout, API_BASE_URL } from '../config/api';
- Uzun işlemler: BackgroundTasks + progress polling endpoint
- Harici API çağrıları: Her zaman timeout parametresi ekle
- Cache: BoundedCache kullan (asla sınırsız dict kullanma)
- Analytics hesaplamaları: `analytics/` modülüne koy (metrics.py, champion_finder.py)
### Frontend
- `fetchWithTimeout` kullan (`src/config/api.js`'den)
- Async işlemler için loading state göster
- Eşzamanlı çağrılar için request deduplication uygula
- Grafikler: Recharts kullan, veri dönüşümü `utils/chartTransformers.js`'de
- Export: `utils/exportUtils.js` ile CSV/Excel
### CORS Değişiklikleri
Yeni frontend portları için `main.py`'deki CORS allowlist'e ekle (satır 34-45):
Yeni frontend portları için `main.py`'deki CORS allowlist'e ekle:
```python
allow_origins=["http://localhost:5173", "http://localhost:5174", ...]
```
## Database
**Dev**: `postgresql://postgres:trendyol123@localhost:5433/trendyol_db`
**Docker**: `postgresql://postgres:trendyol123@postgres:5432/trendyol_db`
Migrations: Alembic (`backend/alembic/`). Her schema değişikliğinde `alembic revision --autogenerate` çalıştır.
| Model | Amaç | Anahtar Alanlar |
|-------|------|-----------------|
| Category | Hiyerarşik kategori ağacı | `parent_id` (self-ref), `trendyol_category_id` |
| Snapshot | Aylık veri görüntüleri | `category_id`, `json_file_path` |
| Report | Kayıtlı raporlar | `category_id`, `json_file_path` |
| EnrichmentError | API hata logları | `endpoint`, `error_type`, `status_code` |
## Deployment
**Platform**: Coolify + Docker Compose + Traefik reverse proxy
Docker Compose servisleri: `postgres` (15-alpine), `backend` (FastAPI), `frontend` (Nginx)
`startup.sh` sırası: PostgreSQL bağlantı bekle → Alembic migration → Kategori seeding → Uvicorn başlat
Traefik SSE streaming desteği: 100ms flush interval (rapor progress için)
## Kaynak Limitleri
| Kaynak | Limit |
@@ -163,26 +213,11 @@ allow_origins=["http://localhost:5173", "http://localhost:5174", ...]
| Sosyal kanıt batch | 5 ürün/istek |
| Rate limit | 2 istek/saniye (sosyal kanıt) |
## Kritik Dependency'ler
**Backend**: FastAPI 0.104.1, SQLAlchemy 2.0.45, Uvicorn 0.24.0, Requests 2.31.0, Pytrends 4.9.2
**Frontend**: React 19.2.0, Vite 7.2.2, Recharts 3.4.1, Tailwind CSS 4.1.17, Axios 1.13.2
## Database Modelleri
| Model | Amaç | Anahtar Alanlar |
|-------|------|-----------------|
| Category | Hiyerarşik kategori ağacı | `parent_id` (self-ref), `trendyol_category_id` |
| Snapshot | Aylık veri görüntüleri | `category_id`, `json_file_path` |
| Report | Kayıtlı raporlar | `category_id`, `json_file_path` |
| EnrichmentError | API hata logları | `endpoint`, `error_type`, `status_code` |
## Dokümantasyon
| Dosya | Amaç |
|-------|------|
| docs/DASHBOARD_ARCHITECTURE.md | **Önemli** - Dashboard veri yapıları |
| docs/DASHBOARD_ARCHITECTURE.md | Dashboard veri yapıları ve KPI tanımları |
| docs/bug-fixes/ORIGINTAB_BUG_FIX.md | **Kritik** - Alan adı uyumsuzluk pattern'i |
| docs/API_DOCUMENTATION.md | Tam API referansı |
| docs/ARCHITECTURE.md | Sistem mimarisi (Türkçe) |