# Site Yönetimi Yenileme — "Voyage" Kapsamlı Planı

## Context

Acente CRM'indeki mevcut Site Yönetimi modülü (`/agency/page` editörü + `/agency/website` ayarları) baştan yenilenecek. Mevcut sistem: acente başına tek sayfa, fiilen tek çalışan tema, panel tasarım dilinden kopuk 1592 satırlık bağımsız editör, sahte DNS doğrulama, domain çözümleme middleware'i yok ve çok sayıda bug (moveUp/moveDown metodları yok, gallery section ölü modele bağlı, publish'te çift revizyon, 8 section tipinin blade'i yok → fatal).

Hedef: **Tek profesyonel template ("Voyage") ile başlayan**, çok sayfalı, standart header/footer/iletişim/canlı destek içeren, WHM/cPanel sunucusunda müşterilerin kendi domainlerini bağlayıp o domainlerde mail hesabı bile açabildiği modern bir site yönetim sistemi. **Ön taraftaki (ziyaretçiye görünen) web mantığı — tur listeleme/detay sayfaları ve controller'ları dahil — komple sıfırdan yazılacak; eski public controller ve blade'lerden hiçbiri yeniden kullanılmayacak.**

**Tasarım referansları:**
- **trivago.com.tr** — kart tasarımları, component kütüphanesi, liste sayfası düzeni (`image.png` referansı)
- **etstur.com** — destinasyon mozaiği (`ets.png` referansı: masonry düzende tam görsel kartlar, alt-sol köşede beyaz destinasyon adı + "N Otel/Tur" sayacı), ürün tipi sekmeli arama barı, kampanya desenleri
- **jollytur.com** — **arama bandı (`jolly.png` — ZORUNLU, birebir bu yapı)** ve **tur/ürün detay sayfası düzeni** (`detay.png`, `detay1.png`, `detay2.png`, `detay3.png`, `detay-4.png`, `rezervasyon.png`, `fiyatlar.png`, `program.png` — birebir aynı düzenin daha modern, profesyonel ve sade hali)
(bkz. "Voyage UI Kit" bölümü)

**Kullanıcı kararları:** WHM **root** erişimi var · Çok sayfalı site · Canlı destek kendi altyapımızla (mevcut chat genişletilecek) · Temiz başlangıç (eski veriler taşınmaz, eski tablolar bir süre yerinde kalır) · Section kütüphanesi acentenin **ürün tipi yetkilerine** bağlı · Akış: **taslakta düzenle → panelde önizle → yayına al** (yayınlanana kadar site herkese kapalı) · **Veri eksiksizliği ilkesi:** sistemin genel yapısı, tutulan bilgiler ve veritabanı şeması kapsamlı incelenerek web sayfasındaki tüm alanlar gerçek CRM verisiyle anlamlı şekilde doldurulacak — **hiçbir veri atlanmayacak** (bkz. "Veri Envanteri ve Alan Eşleme").

---

## Voyage UI Kit — Trivago + Etstur İlhamlı Component Kütüphanesi

Tüm public sayfalar bu ortak kit ile kurulur (`resources/views/site/templates/voyage/components/` + `public/assets/site/voyage/`). Referanslardan birebir kopya değil; kart dili, boşluk/radius/gölge disiplini ve bilgi hiyerarşisi uyarlanır:

- **Tasarım dili:** Beyaz zemin, bol beyaz alan, 8-12px radius (görsel kartlarda 16-20px), ince border + hafif gölge; tek vurgu rengi (acente `design_tokens`'tan) + yeşil "fiyat/CTA" tonu; koyu lacivert footer.
- **`search-band`** (jolly.png — **ZORUNLU bileşen**, ana sayfa hero'sunun çekirdeği) — koyu (lacivert ton, acente rengine uyarlanır) yuvarlatılmış arama bandı, üç katman:
  1. **Ürün tipi sekme butonları** üst sırada (ikonlu, aktif olan açık zemin — Kültür Turu | Günübirlik Tur | ... acentenin ürün tipi yetkilerinden otomatik; "Yeni" rozeti desteklenir),
  2. **Beyaz segmentli input satırı**: Gidilecek Yer/Tur Adı | Tarih (tur tipine göre tek tarih veya giriş/çıkış) | Kişi Sayısı dropdown | **yeşil "HEMEN ARA"** butonu,
  3. **"Popüler Aramalar"** hızlı link pill'leri (editörden yönetilir).
  Liste sayfasında sticky kompakt varyantı kullanılır; sekme seçimi arama sonucunun ürün tipini belirler.
- **`destination-mosaic`** (ets.png birebir referans) — masonry düzende değişken boyutlu tam görsel destinasyon kartları; alt-sol köşede kalın beyaz destinasyon adı + "N Tur" sayacı, alt karartma gradyanı, hover'da hafif zoom; altında "Tüm Bölgeleri Gör" butonu. `destinations` section'ının varsayılan görünümü.
- **`tour-card--horizontal`** (liste sayfası, image.png düzeni): solda görsel karuseli (nokta göstergeli, favori kalbi), ortada başlık + yıldız/etiketler + konum satırı (pin ikonu + mesafe/bölge) + öne çıkan özellik satırı, sağda **fiyat kutusu** (açık yeşil zemin, ✓'li avantaj satırları — "Her Şey Dahil", "Ücretsiz iptal" —, büyük fiyat + küçük "kişi başı/toplam" alt satırı, yeşil CTA "İncele →"). Üst köşede kampanya şeridi ("%25 daha düşük" tarzı koyu kırmızı rozet).
- **`tour-card--vertical`** (ana sayfa vitrini): görsel üstte, ad + konum, puan rozeti, kırmızı indirim rozeti, fiyat/gece + tarih aralığı + iptal notu, dairesel ok CTA.
- **`rating-pill`** — koyu yeşil kare puan + "Mükemmel (1.2B yorum)" etiketi (yorum altyapısı Faz 5; ilk fazda testimonial/etiket gösterimi).
- **`badge` ailesi** — indirim (koyu kırmızı), bilgi (mavi ton), "En uygun fiyat" (yeşil çip), kampanya şeridi.
- **`filter-sidebar`** — liste sayfası sol paneli: fiyat histogramı + çift uçlu aralık slider'ı, genişleyebilir onay kutusu grupları (kategori, süre, bölge...), altta sticky "N sonuç göster" butonu.
- **`filter-chips`** — liste üstü yatay pill filtre çubuğu (aktif durum renkli, x ile kaldırma).
- **`inline-detail-tabs`** — trivago'nun kart içi genişleyen sekmeleri (Fiyatlar/Fotoğraflar/Bilgi) deseni → tur kartında hızlı bakış; tam detay sayfası da ayrıca var.
- **`photo-mosaic`** — detay sayfası galeri mozaiği (caption overlay'li karo düzeni + "Tüm fotoğrafları göster" karosu + lightbox).
- **`highlight-card`** — "Bilmeniz gerekenler" tarzı: başlık + açıklama + görsel + etiket çipleri (tur programı öne çıkanları için).
- **`promo-strip`** — tam genişlik renkli kampanya/duyuru bandı (ikon + metin + CTA).
- **`campaign-stories`** (Etstur deseni, Faz 5) — Instagram-story tarzı dairesel kampanya kartları şeridi; tıklanınca kampanya detayı/ilgili tur listesi.
- **`theme-cards`** (Etstur "Tatil Temaları" deseni) — yatay kaydırmalı tema kartları (Balayı, Aile, Kültür... → tur kategorilerine bağlanır); `tour_categories` section'ının bir varyantı.
- **`info-widget`** — sekmeli bilgi kutusu (trivago "en iyi zaman" widget'ı deseni → "Ayın turları", "Sezon takvimi" gibi kullanımlar).
- **`section-header`**, **`sticky-header`** (scroll'da kompaktlaşan), **`map-panel`** (Faz 5 — fiyat pinli harita).
- **`footer`** (Etstur deseni) — koyu lacivert çok sütunlu footer + üstünde açık zeminli "Popüler Bölgeler/Turlar" SEO link bloğu + sosyal ikon şeridi + telefon/çağrı vurgusu.

---

## Veri Envanteri ve Alan Eşleme — Hiçbir Veri Atlanmayacak

Sistemin veritabanı yapısı kapsamlı incelendi. Web sayfası alanları aşağıdaki gerçek CRM verileriyle beslenecek; **veri varsa mutlaka gösterilir, yoksa bölüm sekmede/sayfada hiç görünmez**:

### Ana veri kaynakları
- **Omurga:** `ProductType` (4 tip: kültür/günübirlik/yurtdışı/ekstra-hizmet; `has_itinerary/has_dates/has_pricing/has_booking` yetenek bayrakları **detay sayfasında hangi sekmelerin çizileceğine karar verir**) + `Product` (slug, kategoriler, pazaryeri, çeviriler).
- **Turlar:** `Tour` (cultural_tours) ≡ `InternationalTour` (aynı alan seti — tek şablonla render edilir), `DayTour` (saat bazlı + `recurring_days` + `allows_custom_booking` → "özel tarih talebi" formu), `ExtraService`, `ServiceProduct`.
- **Fiyat:** `TourDate`/`DayTourDate` (tarih, kontenjan, sezon, durum, indirimler, garantili kalkış, ödeme/iptal kuralları) + `TourDateMarketplacePrice` (**gerçek fiyat kaynağı**: adult/child_1/child_2/infant, `single_supplement`, `extra_bed_price`) + `TourClass` sınıf sistemi (Ekonomi/Business fiyat kolonları) + `ProductMarketplacePrice` ("...'den başlayan" fallback).
- **Program:** `*TourItinerary` tabloları (day_number/title/description/location; günübirlikte time/duration/activity_type/koordinat) + gün görselleri (`TourImage section='itinerary'` + `day_number`).
- **Medya:** `TourImage` (is_cover/show_in_gallery/show_in_slider/section bayrakları) → `DiskItem` (thumbnails srcset, dominant_color → LQIP placeholder, webp, alt/caption).
- **Kalkış noktaları:** `*TourTransferPoint` (departure/transfer, pickup_time, koordinat; `has_transfer_points` koşulu).
- **Acente/güven:** `Agency` (tursab_number + belge dosyaları, legal_name, vergi bilgileri, iletişim, sosyal, `bank_accounts[].show_on_site` → `publicBankAccounts()`), `AgencyCertificate` (`show_on_website`), `AgencyStaff` (ekip section'ı).
- **Rezervasyon köprüsü:** Web talebi → `Sale` (customer_id nullable, `source=web`, tour_date polimorfik) + `SaleRoom` (oda tipleri) + `SalePassenger`; kontenjan `TourDate::reserveCapacity()` hazır.
- **Çok dillilik (hazır altyapı, ileriki faz):** `Marketplace` + `ProductMarketplaceTranslation` (name/description/highlights/inclusions/exclusions/meta çevirileri).

### Detay sayfası bölüm → alan eşlemesi (özet)
| Bölüm | Kaynak |
|---|---|
| Galeri kolaj | `TourImage`(slider/gallery/cover) + `DiskItem`, `video_url` |
| Başlık + rozetler | `name`, `is_featured/is_bestseller/is_new`, `starting_price`, `rating_*` |
| Özet kutusu | süre (`days/nights` veya `duration_hours`), `departureCity→arrivalCity`, `transportation_method`, `has_guide`+`languages`, `difficulty_level`, kontenjan |
| Genel bilgiler | `description`, `places_to_visit`, `requirements`, `difficulty_description` |
| Tur programı | `*TourItinerary` + gün görselleri |
| Fiyatlar & Tarihler | `TourDate` satırları + `TourDateMarketplacePrice` kolonları (yaş bantları tur/tarih alanlarından dinamik başlıklarla) |
| Dahil/Hariç | `inclusions`/`exclusions` |
| Ulaşım | `transportation_*`, uçuş alanları (`departure/arrival_airports`, flight no/saatler), `distance_km`, araç: `Resource`+`ResourceImage` |
| Kalkış noktaları | `*TourTransferPoint` (departure) |
| Kampanya rozetleri | `TourDate.early_booking/last_minute/group/special_discount` + deadline çözücüleri + `discount_reason` |
| Ödeme | `payment_plan`, `deposit_*`, `online_payment_enabled`, havale: `publicBankAccounts()` |
| İptal/şartlar | `cancellation_policy`, `terms_conditions`, `refundable`, deadline'lar |
| Çocuk politikası | `child/infant_min/max_age`, `child_friendly`, `infant_allowed` |
| Harita | departure/arrival + transfer + itinerary koordinatları |
| Belgeler | `documents` (JSON) |
| Güven şeridi | `Agency` TÜRSAB/sertifika/iletişim + `AgencyCertificate` |
| SEO | `meta_*`, `tags`, `slug`, og_image; JSON-LD (schema.org TouristTrip) mevcut alanlardan türetilir |

### Zorunlu web filtreleri
Turlar: `is_active + is_public + !is_draft` (+ published_at/expires_at) · Tarihler: `is_active + is_published + is_bookable + !is_private` (**özel kalkışlar asla sızmaz**) · Görseller: `is_active + is_approved` · Sertifikalar: `show_on_website` · Banka: `show_on_site` · Kategoriler: `is_active + is_public`.

### Tespit edilen veri boşlukları
- **Faz 1'de eklenecek küçük migration'lar:** itinerary tablolarına `meals` + `accommodation` alanı (Jolly'nin "Konaklama: X Otel / Yemek: KÖA" satırı), tur tablosuna `highlights` (madde madde öne çıkanlar), `DayTourTransferPoint`'e `point_type`.
- **Faz 5'e planlananlar:** `tour_reviews` tablosu (rating_average/count kolonları zaten var, besleyen tablo yok), yapılandırılmış SSS tablosu (tur bazlı + genel), kampanya modeli (ad/banner/kupon/kapsam), tur↔otel ilişkisi (`SupplierHotelFactSheet` mevcut ama tura bağlı değil), çoklu video, benzer turlar, blog.

---

## Faz 1 — Çekirdek Veri Modeli + Voyage Template + Public Web'in Sıfırdan Yazımı

### 1a. Yeni veri modeli (temiz başlangıç)

Tek migration: `database/migrations/xxxx_create_agency_sites_tables.php`

- **`agency_sites`** — acente başına 1 site: `agency_id` (unique), `template_key` (default `voyage`), `status` (draft/published), `published_revision_id`, `design_tokens` json (renk/font/radius), `header_config` json, `footer_config` json, `chat_config` json, `seo_defaults` json, `custom_css`, `custom_js`, `head_scripts`, `body_scripts`
- **`agency_site_pages`** — çok sayfalılık: `site_id`, `type` (`home`|`contact`|`tours`|`tour_detail`|`custom`), `slug` (İngilizce, home=null), `title`, `meta` json, `show_in_nav`, `nav_label`, `nav_order`, `is_active`. `home` ve `contact` silinemez (standart).
- **`agency_site_sections`** — `page_id`, `section_type`, `sort_order`, `is_active`, `settings` json, `data` json. Sıralama tek `reorder` endpoint'i ile.
- **`agency_site_revisions`** — site düzeyinde snapshot (site + tüm sayfalar + section'lar). **Revizyon yalnızca servis katmanında explicit oluşturulur** (çift revizyon bug'ı tekrarlanmaz).
- **`site_form_submissions`** — `agency_id`, `page_id`, `form_key` (`contact`|`chat_offline`), `payload` json, `visitor_ip`, `status` (new/read/converted), `customer_id` nullable.

Ek küçük migration'lar (veri boşlukları): `*_itineraries` tablolarına `meals` + `accommodation`, tur tablolarına `highlights` (json), `day_tour_transfer_points`'e `point_type`.

Yeni modeller: `app/Models/Site/{AgencySite, AgencySitePage, AgencySiteSection, AgencySiteRevision, SiteFormSubmission}.php`
Yeni servis: `app/Services/Site/SiteService.php` (davranış referansı: `app/Services/Agency/AgencyPageService.php`; kod yeniden kullanılmaz)

**Template registry DB'de değil kodda:** `config/site-templates.php` + `app/Services/Site/Templates/VoyageTemplate.php` (manifest: section tipleri, varsayılan settings/data, design token defaults). `agency_themes` tablosu terk edilir.

### 1b. Section kütüphanesi — ürün tipi yetkilerine bağlı

Section manifest'inde her tanım `required_product_types` taşır; `SiteService::getAvailableSections(Agency $agency)` **acentenin aktif ürün tipi yetkileriyle** (mevcut ürün tipi sistemi: `kultur-turu`, `gunubirlik-tur`, ekstra hizmetler...) kesiştirir:

- **Genel section'lar** (yetkiden bağımsız): hero, about, destinations, testimonials, gallery (Disk modülüne bağlı), stats, faq, cta, certificates (`agency_certificates.show_on_website` hazır), custom_html, promo_strip.
- **Ürün tipine bağlı section'lar:** tour_showcase (vitrin), tour_search (arama barı), tour_categories — yalnızca ilgili ürün tipi yetkisi olan acentede listelenir; yetki sonradan kaldırılırsa mevcut section public render'da otomatik gizlenir (fatal değil, sessiz skip).
- Editördeki "Bölüm Ekle" gridi de aynı filtreden beslenir; yetkisiz tip hiç gösterilmez.

### 1c. Public web — komple sıfırdan (eski controller/blade'ler emekli)

**Emekli edilenler:** `app/Http/Controllers/Page/AgencyPageController.php` (show/searchTours/listTours/showTour), `Page/ContactController.php`, `resources/views/page/agency/**` (index, search-results, themes/default tamamı, tours/* ~1600 satırlık blade'ler), `App\View\Components\AgencyThemeLayout`. Faz 1 sonunda eski route'lar yeni sisteme yönlendirilir; dosyalar Faz 5'te silinir.

**Yeni public katman** (`routes/site.php` + `app/Http/Controllers/Site/`):
- `SitePageController` — home/contact/custom sayfaları yayınlanmış snapshot'tan render.
- `SiteTourController` — **tur listeleme + tur detay + arama sıfırdan**: Voyage UI Kit ile liste sayfası (filter-sidebar + filter-chips + tour-card--horizontal + sıralama + sayfalama). Veri mevcut tur modellerinden (kültür turu / günübirlik tur) okunur; ürün tipi yetkisi olmayan tipin route'u 404.

**Tur detay sayfası — Jolly deseni (detay*.png, rezervasyon.png, fiyatlar.png, program.png), modern/sade uyarlama:**
1. **Galeri kolaj hero** (detay.png): breadcrumb + karışık boyutlu foto/video kolajı; sol altta **başlık overlay kartı** (tur adı + "Öneriyoruz" rozeti + konum + paylaş), sağda **aksiyon sidebar'ı**: Haritada Göster / Tüm Fotoğraflar butonları, konsept-özet satırları (konaklama tipi, süre vb.), **"Biz Sizi Arayalım"** (→ `site_form_submissions`, `form_key=callback`) ve **"Canlı Destek"** (Faz 4 widget'ı açar) butonları.
2. **Sticky sekme navigasyonu** (rezervasyon.png üst şerit): `Rezervasyon | Tur Programı | Fiyatlar & Tarihler | Bilgiler | Kampanyalar` — sekmeler scroll-spy ile bölümlere kayar; altında **tarih/kişi seçim barı + "Değiştir"**.
3. **Rezervasyon bölümü** (rezervasyon.png/detay1.png): seçenek kartları (görsel + ad + konsept/board + ücretsiz iptal + indirim rozeti + üstü çizili fiyat + toplam fiyat + radio seçim, seçili kart yeşil çerçeve/zemin; genişleyen "Özellikler / Gecelik Fiyatlar / Müsaitlik" satırı) + sağda **sticky "Rezervasyon Detayları" özet paneli** (tarih, süre, seçim, indirim dökümü, toplam, yeşil "Rezervasyon Talebi" CTA). İlk fazda CTA **rezervasyon talep formu** oluşturur (`site_form_submissions` → panelde lead/satışa dönüştürme); online ödeme ileriki faz.
4. **Tur Programı bölümü** (program.png): gün gün akordiyon/timeline — her gün: başlık, **güzergah chip'leri**, anlatım, yeme-içme bilgisi; sağ sidebar: **"Programı E-posta Gönder" / "Programı İndir (PDF)"** butonları, **Ulaşım Bilgisi** (segment listesi), **Transfer/Hareket Noktaları**, **Ücrete Dahil Olan / Olmayan Hizmetler** listeleri.
5. **Fiyatlar & Tarihler bölümü** (fiyatlar.png): kalkış tarihine göre akordiyon; her tarihte **fiyat tablosu**: iki kişilik oda kişi başı | tek kişilik | ilave yatak | bebek/çocuk yaş bantları — üstü çizili eski fiyat + güncel fiyat + satır sonunda "Rezervasyon Talebi" butonu.
6. **Bilgiler bölümü** (detay2/detay3.png): istatistik çipleri (alan, oda/kontenjan sayısı vb.), uzun açıklama, madde listeleri, **konsept bölümü** (kategori başlıkları altında saat çipli hizmet grid'i), aktivite listeleri, sağ kolonda ikonlu bilgi kartları (Yeme-İçme, Balayı vb. — içerik varsa).
7. **Puan & Yorumlar** (detay-4.png — Faz 5 yorum altyapısıyla): büyük puan kutusu + ödül kartları, kitle filtreleri (Aileler/Çiftler), değerlendirme özeti, kategori bazlı puan satırları.
Tüm bölümler **veri varsa render edilir** (boş bölüm sekmede görünmez); alan eşleme "Veri Envanteri ve Alan Eşleme" bölümüne göre yapılır — hiçbir mevcut veri atlanmaz. Detay sekmelerinin hangilerinin çizileceğine `ProductType` yetenek bayrakları (`has_itinerary/has_dates/has_pricing/has_booking`) karar verir (ör. günübirlik turda gün-gün program yerine saat bazlı akış, ekstra hizmette fiyat tablosu yerine birim fiyat).
- `SiteFormController` — iletişim + tur bilgi talebi formları → `site_form_submissions` (rate limit + honeypot); panelde lead'e dönüştürme.
- Route şeması (İngilizce): `/` (home), `/tours`, `/tours/{type}`, `/tours/{type}/{slug}`, `/contact`, `/p/{slug}` (custom sayfalar).

**Yayın akışı (netleştirme):** Site oluşturulduğunda `draft` durumundadır ve public'te **404 döner**. Acente editörde düzenler → **panel içi önizleme** (draft render, sadece oturumlu acente kullanıcısı erişir, `SitePreviewController`) → "Yayına Al" ile snapshot alınır ve site herkese açılır. Sonraki düzenlemeler yine draft'ta birikir; ziyaretçi her zaman son yayınlanan snapshot'ı görür.

### 1d. Standart bölgeler + iletişim sayfası

- **Header** (`header_config`): logo modu (light/dark), sayfalardan otomatik menü + özel linkler, telefon, CTA butonu, sticky davranış (Voyage `sticky-header` bileşeni).
- **Footer** (`footer_config`): koyu çok sütunlu düzen; iletişim bilgileri (`agencies.contact_*` fallback), sosyal linkler, çalışma saatleri, yasal linkler.
- **İletişim sayfası** (standart, silinemez): form + harita (embed/lat-lng) + bilgi kartları + SSS bloğu.

### 1e. Marka / kimlik yönetimi

- Migration: `agencies` tablosuna `logo_dark_path`, `favicon_path`, `brand_colors` json (mevcut `logo` = light varyant).
- Yeni **Branding drawer ekranı** (quick-view pattern) — `agency/settings/branding`; logo/favicon yükleme. Upload: `storage/app/public/agencies/{id}/brand/`.
- `Agency::getPublicUrlAttribute()` bug'ı düzeltilir.

---

## Faz 2 — Editör UX Yenilemesi (canlı önizlemeli)

- Editör tam ekran kalır ama panel diline geçer: Bootstrap 5.3 + `assets/agency/css/app.css` token'ları + dark-theme + `appToast`. Yeni `resources/views/agency/site/editor.blade.php` + parçalanmış partial'lar (eski 1592 satırlık monolit emekli).
- **Canlı önizleme:** solda sayfa + section listesi (SortableJS lokal asset), sağda draft render eden iframe (`Agency\Site\SitePreviewController`); postMessage köprüsü ile section highlight / tıkla-düzenle. Masaüstü/tablet/mobil önizleme anahtarı.
- Section düzenleme: iframe'de tıklanan section drawer formu açar (quick-view bileşen sınıfları); kaydet → sadece o section partial-render ile yenilenir.
- Sayfa yönetimi (ekle/sil/slug/SEO/nav) editör içi "Pages" paneli. `custom_css/js`, `og_image` ilk kez UI'a bağlanır. Draft/publish/revisions UI korunur.
- Section preset varyantları (manifest'te `variants` — ör. hero'nun statik/slider/arama-barlı 3 varyantı), sayfa bazlı SEO paneli.

## Faz 3 — Domain Bağlama + cPanel/WHM Entegrasyonu + Mail

### Mimari (araştırma sonucu, WHM root ile)
Tek cPanel hesabı (Laravel app) + müşteri domainleri **alias (UAPI `Park::park`)** olarak eklenir (ortak vhost/docroot = app public). Çağrılar **WHM root token proxy** ile (`:2087/json-api/cpanel?...`, header `Authorization: whm root:TOKEN`, token'a ACL kısıtı). Ön koşullar (kullanıcı yapacak): WHM Tweak Settings → **Allow Remote Domains** + Allow Unregistered Domains açık; pakette MAXPARK/MAXADDON unlimited; AutoSSL sağlayıcı seçili.

### Servis katmanı
- `app/Services/Cpanel/CpanelGateway.php` (interface): `parkDomain`, `unparkDomain`, `triggerAutoSsl`, `getSslStatus`, `createMailbox`, `deleteMailbox`, `changeMailboxPassword`, `listMailboxes`.
- Sürücüler: `WhmApiGateway` (Laravel `Http` client ~100 satır — paket bağımlılığı yok), `LogGateway` (local dev: sahte başarı + log). Seçim `.env CPANEL_DRIVER=log|whm`.
- `app/Services/Site/DomainProvisioningService.php` — durum makinesi: `pending → dns_verified → provisioned → ssl_active`. Queue job'ları: `VerifyDomainDnsJob`, `ProvisionDomainJob`, `CheckSslStatusJob` (idempotent).

### Akış
1. Acente domainini girer → benzersiz TXT token; DNS talimatları (TXT + A kaydı; mail için MX/SPF/DKIM veya nameserver değişimi — nameserver modu mail için önerilir, MX/DKIM otomatik).
2. Job DNS'i poll eder (`dns_get_record`): TXT → sahiplik, A kaydı → trafik. (Sahte `checkDnsRecords` kalkar.)
3. `Park::park` → vhost + zone; `start_autossl_check_for_one_user` → `SSL::installed_hosts` poll → panelde "SSL aktif".
4. Yeni middleware `app/Http/Middleware/ResolveSiteHost.php`: Host header → custom_domain (verified) veya `{subdomain}.{platform}` → Agency resolve; `/agency/{slug}` fallback kalır.
5. Domain blocklist (gmail.com vb.), "aynı domain başka hesapta" hatası anlaşılır gösterilir; offboarding (mail sil → unpark → zone temizliği).

### Mail modülü entegrasyonu
Domain drawer'ına **"Mail Hesapları"** bölümü: `info@kendidomaini.com` → UAPI `Email::add_pop` (quota) → otomatik `MailAccount` kaydı (IMAP: sunucu hostname:993 SSL, SMTP: 587 STARTTLS, kullanıcı = tam adres, parola encrypted cast — model hazır) → mevcut `MailSyncService`/`MailSendService` devralır. Sil/parola → `delete_pop`/`passwd_pop`. Webmail linki (`:2096`).

## Faz 4 — Ziyaretçi Canlı Desteği (B2C)

Mevcut chat altyapısı yeniden yazılmaz, genişletilir:
- `conversations.type` → yeni `visitor` değeri; yeni `site_visitors` tablosu (`uuid_token`, `agency_id`, `name`, `email`, `last_seen_at`); imzalı cookie ile misafir kimliği.
- Public endpoint'ler: `app/Http/Controllers/Site/SiteChatController.php` (start/messages/send). Reverb: `routes/channels.php`'ye `site.visitor.{token}` kanalı; Reverb yoksa mevcut hibrit polling deseni.
- Panel: visitor konuşmaları mevcut `chat-widget.blade.php`'ye yeni sekme; ilk yanıtlayan personel claim eder. `ChatController`'a minimal ekleme.
- Offline fallback: aktif personel yoksa widget iletişim formuna dönüşür → `site_form_submissions` (`chat_offline`).
- Voyage `chat-widget` bileşeni; `chat_config` (karşılama metni, açık/kapalı, çalışma saatleri) editörden yönetilir.

## Faz 5 — Rakip İlhamlı Ekstralar

Öncelik sırasıyla: otomatik sitemap.xml/robots + Google snippet önizleme · **`tour_reviews` tablosu + misafir yorumları/puan sistemi** (Jolly detay-4 deseni: puan kutusu, kitle filtreleri, kategori puanları — `rating_average/count` kolonları hazır) · **kampanya modeli** (ad/banner/kupon/geçerlilik/kapsam; `campaign-stories` + duyuru barı bununla beslenir) · **yapılandırılmış SSS tablosu** (tur bazlı + genel) · **tur↔otel ilişkisi** (`SupplierHotelFactSheet` tura bağlanır → detayda otel bilgi kartları) · Disk modülü medya picker'ı · tur liste sayfasına harita paneli (`map-panel`, fiyat pinli — trivago deseni) · basit ziyaret istatistikleri (GA4 alanı Faz 1'de hazır) · blog · benzer turlar · çoklu video · `site:migrate-legacy` + eski dosya/tabloların silinmesi.

---

## Kritik referans dosyalar

- `app/Services/Agency/AgencyPageService.php` — yalnızca davranış referansı (kod taşınmaz)
- `routes/agency.php:781-801, 1062-1067` + `routes/web.php:29-36` — değiştirilecek/emekli edilecek route grupları
- `resources/views/page/agency/**` — tamamı emekli edilecek eski public katman
- `resources/views/agency/page/editor.blade.php` — eski editör davranış referansı
- `app/Http/Controllers/Agency/AgencyWebsiteController.php` — domain UI yenilenir, sahte DNS doğrulama kalkar
- `app/Http/Controllers/Agency/ChatController.php`, `resources/views/agency/layouts/partials/chat-widget.blade.php` — Faz 4 entegrasyon noktaları
- `app/Models/Mail/MailAccount.php` — cPanel kutusu → MailAccount otomasyonu
- `resources/views/components/quick-view-drawer.blade.php` — drawer ekranları bu pattern'le
- `C:\xampp\htdocs\acente\image.png` — liste sayfası tasarım referansı (trivago arama sonuçları düzeni)
- `C:\xampp\htdocs\acente\ets.png` — destinasyon mozaiği tasarım referansı (etstur "Popüler Bölgeler" düzeni)

## Doğrulama

- **Faz 1:** `php artisan migrate` (kullanıcı çalıştırır) → yeni acente sitesi draft'ta → public 404 doğrulanır → panelde önizleme çalışır → "Yayına Al" → `/agency/{slug}` üzerinden home/contact/tur listesi/tur detay render. Ürün tipi yetkisi olmayan acentede tur section'larının/route'larının görünmediği test edilir. İletişim formu panele düşer, lead'e dönüşür. Chrome ile trivago referansına karşı görsel kontrol.
- **Faz 2:** Editörde section ekle/sırala/düzenle → iframe canlı güncellenir → Yayınla → public'te snapshot görünür, draft görünmez.
- **Faz 3:** Local'de `CPANEL_DRIVER=log` ile uçtan uca durum makinesi; gerçek sunucuda test domaini ile `uapi Park park` canlı doğrulama, AutoSSL sonrası https; oluşturulan mail kutusuna mevcut mail modülünden send/sync testi. (`php artisan queue:work` gerekli.)
- **Faz 4:** İki tarayıcı (ziyaretçi + personel) ile canlı mesajlaşma; personel yokken offline form.

## Notlar / Kısıtlar

- Artisan komutlarını kullanıcı çalıştırır; URL'ler İngilizce; yönetim ekranları mümkün olduğunca quick-view/drawer pattern'inde (editör tam ekran istisna); Voyage tasarımında frontend-design skill kullanılacak.
- Trivago ve Etstur **ilham** kaynağıdır: kart düzeni, bilgi hiyerarşisi, boşluk/radius disiplini uyarlanır; logo/marka/birebir kopya yapılmaz.
- Eski tablolar ve `resources/views/page/**` Faz 5'e kadar silinmez; eski route'lar Faz 1'de yeni sisteme yönlendirilir.
- Çoklu template'e hazır mimari: `template_key` + manifest registry.
