# exripe Tema Geliştirme Sözleşmesi (AI / Cursor)

> **Bu dosyayı oku ve uygula.** Cursor veya Claude’a `@docs/theme.md` veya bu dosya yolu verildiğinde tema geliştirme kuralları buradan gelir.
> İnsan okumalı HTML: `docs/theme.html` · Makine özeti: `docs/theme.contract.json`

## AI AGENT INSTRUCTIONS

1. exripe temaları **PHP SSR** view’lardır. React/Next/headless tema yazma.
2. Referans uygulama: `themes/primex/`. Yeni tema için Primex’i kopyala; iş mantığını (`app/`, `core/`) değiştirme.
3. Sepet sunucuda değil: `localStorage['exripe_cart']`. Alan adlarını değiştirme.
4. Storefront JSON uçları aşağıda listelenir; `/api/admin/*`, `/api/store-*`, hub uçlarını temada kullanma.
5. Metinler: `lang('key', 'fallback')` — tema içi `locales/*.json` yok.
6. Asset URL: `$temaCssUrl` veya `$themeAssetUrl . '/assets/...'`.
7. Partial: `require __DIR__ . '/partials/....php';` (alt klasörde `../partials/`).
8. Değişiklik sonrası Admin → Tema Yönetimi’nden aktif et veya ZIP ile yükle (`POST /admin/themes/upload`).

---

## Mimari

```
HTTP → Controller (veri hazırlar)
     → ThemeManager::render($view, $data)
     → themes/{aktif}/views/{view}.php
     → (yoksa) templates/{view}.php fallback
```

| Parça | Dosya |
|--------|--------|
| Motor | `core/ThemeManager.php` |
| Kayıt | `app/Models/Theme.php` |
| ZIP kurulum | `app/Services/ThemeInstaller.php` |
| Ayarlar | `app/Models/ThemeSettings.php` |
| Bölümler | `app/Models/ThemeSection.php` |
| Referans tema | `themes/primex/` |

Fallback klasör: `primex`.

---

## Klasör yapısı

```
themes/{folder}/
├── theme.json          # zorunlu; folder === dizin adı
├── assets/
│   └── tema.css        # varsayılan ana CSS
├── views/
│   ├── partials/
│   ├── home.php
│   ├── category.php
│   ├── product-detail.php
│   ├── cart.php
│   ├── search.php
│   ├── checkout.php
│   ├── page.php
│   ├── auth/login.php, auth/register.php, …
│   └── account/…
└── screenshots/preview.png   # opsiyonel
```

---

## theme.json

```json
{
  "name": "Tema Adı",
  "folder": "my-theme",
  "version": "1.0.0",
  "author": "…",
  "description": "…",
  "cover": "cover.jpg",
  "required_views": ["home", "category", "product-detail", "cart", "search", "checkout", "page", "auth/login", "auth/register"]
}
```

- `folder`: `^[a-z0-9][a-z0-9_-]*$` ve dizin adıyla aynı olmalı.
- Çekirdek zorunlu view listesi: `Theme::CORE_REQUIRED_VIEWS`.
- Admin listesi eksik view / geçersiz manifest uyarısı gösterir.

---

## ThemeManager otomatik değişkenleri

Her `render()` çağrısında:

| Değişken | Anlam |
|----------|--------|
| `$themeFolder` | Aktif klasör |
| `$baseUrl` | Mağaza kök URL (slash’sız) |
| `$themeAssetUrl` | `{baseUrl}/themes/{folder}` |
| `$temaCssUrl` | Ana CSS (varsayılan `assets/tema.css`) |
| `$seoBrand` | SEO marka eki |
| `$homeMetaTitle` | Ana sayfa title |
| `$homeMetaDescription` | Ana sayfa description |
| `$defaultOgImage` | Varsayılan OG |
| `$csrfField` | CSRF hidden input HTML |

Controller’ların sık geçirdiği ortak alanlar: `$themeSettings` / `$ts`, `$categories`, menüler.

Sayfa örnekleri:

- **home:** `$sections`, `$sectionProducts`, `$banners`
- **category:** `$category`, `$products`, sayfalama, filtreler
- **product-detail:** `$product`, varyantlar, yorumlar, wishlist
- **cart:** kargo eşiği vb. (satırlar istemci)
- **checkout:** ödeme, adres, vergi, onay
- **search:** `$query`, `$products`, sayfalama

---

## Sepet sözleşmesi (zorunlu)

Anahtar: `localStorage['exripe_cart']` → JSON **dizi**.

Satır objesi (Primex ile uyumlu):

```json
{
  "productId": 123,
  "variantId": 456,
  "name": "Ürün adı",
  "slug": "urun-slug",
  "color": "Siyah",
  "size": "M",
  "price": 199.9,
  "compare_at_price": 249.9,
  "quantity": 1,
  "image": "https://…/img.webp"
}
```

- `variantId` ile satır birleştirilir.
- Kupon: `localStorage['exripe_coupon_code']`.
- Güncelleme olayı: `window.dispatchEvent(new CustomEvent('cart-update'))`.
- Sipariş: form `POST /odeme` + CSRF (`$csrfField`).

Doğrulama uçları: `POST /api/coupon/validate`, `POST /api/campaigns/calculate`.

---

## Storefront API (tema runtime)

Tüm yollar `$baseUrl` köküne göredir. JSON. Admin/hub değil.

### Katalog / arama

| Metot | Uç |
|-------|-----|
| GET | `/api/category/{slug}/products` |
| GET | `/api/product/realtime?slug=` |
| GET | `/api/product/{id}/first-variant` |
| GET | `/api/product/{id}/card-quick` |
| GET | `/api/variant/{id}` |
| GET | `/api/search?q=&limit=` |
| GET | `/api/search/suggest` |

### Kupon / kampanya / taksit

| Metot | Uç |
|-------|-----|
| POST | `/api/coupon/validate` |
| POST | `/api/gift-card/validate` |
| POST | `/api/campaigns/calculate` |
| POST | `/api/spin-wheel/apply-coupon` (alias: `/api/cart/apply-coupon`) |
| GET | `/api/paytr-installments` |

### Müşteri

| Metot | Uç |
|-------|-----|
| POST | `/api/wishlist/toggle` body: `{ "product_id": n }` |
| POST | `/api/review/submit` |
| POST | `/api/back-in-stock/subscribe` |
| POST | `/api/customer-login` |
| POST | `/api/customer-register` |

### Checkout yardımcı

| Metot | Uç |
|-------|-----|
| POST | `/api/checkout-hold` |
| POST | `/api/checkout-hold/release` |
| POST | `/api/abandoned-cart` |
| POST | `/api/checkout-snapshot` |
| POST | `/odeme` |

### Pazarlama

| Metot | Uç |
|-------|-----|
| GET | `/api/spin-wheel/config` |
| POST | `/api/spin-wheel/spin` |
| GET | `/api/marketing-automation/rules` |
| POST | `/api/marketing-automation/event` |
| POST | `/api/meta/capi` |
| GET | `/api/visitor-heartbeat` |

**Kullanma:** `/api/store-*`, `/api/admin/*`, `/api/plugin-*`, yazılım güncelleme, lisans.

---

## Bölüm tipleri (ThemeSection)

Admin customize sabit tipler: `slider`, `text_slider`, `banner`, `banner_grid`, `product_list`, `marquee`, `text_block`, `image_text`, `brand_images`.

Sayfalar: `home`, `cart`, `footer`.

Tema yeni tip kaydedemez; Primex partial’larıyla aynı tipleri render et.

---

## Çeviri

```php
<?= htmlspecialchars(lang('frontend.cart.empty', 'Sepetiniz boş')) ?>
```

Admin → Dil Dizeleri. Tema-özel locale dosyası yok.

---

## Kurulum / paketleme

1. Geliştir: `cp -R themes/primex themes/my-theme` → `theme.json` güncelle.
2. ZIP: kökte `theme.json`, `views/`, `assets/` (iç içe ekstra klasör olmasın veya tek alt klasör).
3. Admin → Tema Yönetimi → **Tema yükle (ZIP)** veya sunucuya `themes/{folder}/` kopyala.
4. Aktif et.

Kod: `ThemeInstaller`, route `POST /admin/themes/upload`.

---

## Yapılacaklar (bilinçli sınırlar)

- Sunucu sepet CRUD yok — localStorage sözleşmesine uy.
- Tema `theme.json` ile kendi settings şemasını tanımlayamaz — `ThemeSettings` çekirdekte.
- Headless React tema desteklenmez.

---

## Hızlı kontrol listesi (AI)

- [ ] `theme.json` folder === dizin adı
- [ ] Zorunlu view’lar mevcut
- [ ] `$temaCssUrl` / `$themeAssetUrl` kullanıldı
- [ ] Sepet `exripe_cart` şemasına uyuyor
- [ ] Wishlist/search/checkout Primex API uçlarını kullanıyor
- [ ] `lang()` kullanıldı; hardcode metin minimum
- [ ] İş mantığı `app/` içine taşınmadı
