# Yapısal veri (JSON-LD), `
` etiketleri, bağlantı `rel`, izin (consent)
> Ölçüt: `E:\localhost\docs\` bilgi bankası. Framework bu talimatlara BİREBİR uyar; proje yalnız **veri** verir, çıktıyı framework üretir.
> Projede istisna, açma anahtarı, geriye dönük uyum YOKTUR.
## 1. Sayfa türü → JSON-LD
Tek yol: `View::schema(, )` → `SchemaProvider::build()` → `SchemaPreset::execute()` → `SchemaBuilder` → `SchemaProvider::render()` (tek `@graph`, `SchemaPolicy` kapısından geçer).
| Tür | Blok | BreadcrumbList |
|---|---|---|
| `corporate` | Organization (+ LocalBusiness alt tipi) + WebSite | — |
| `home` | WebPage | yok |
| `about`, `faq`, `legal`, `guide`, `page` | WebPage | Anasayfa → sayfa |
| `contact` | ContactPage | Anasayfa → sayfa |
| `blogList` | CollectionPage | Anasayfa → Blog |
| `blogCategory` | CollectionPage | Anasayfa → Blog → kategori |
| `blogPost` | BlogPosting (`og:type=article`) | Anasayfa → Blog → kategori → yazı |
| `productList` | CollectionPage + ItemList | Anasayfa → … → liste |
| `productDetail` | Product + Offer | Anasayfa → Ürünler → ürün |
| `service` | Service | Anasayfa → hizmet |
| `newsArticle` | NewsArticle (`og:type=article`) | Anasayfa → Haberler → haber |
| `tvSeries` | TVSeries | Anasayfa → Diziler → dizi |
| `movie` | Movie | Anasayfa → Filmler → film |
| `person` | Person | Anasayfa → Oyuncular → kişi |
`FrontendBaseController::render()` her sayfaya `corporate` türünü ekler (kurum + WebSite her sayfada). Kurum verisi: `company`/`contact`/`social` ayarları, üstüne controller'ın `$localBusinessData` anahtarları (`SchemaBuilder::organization()` açıklaması: `id`, `type`, `name`, `url`, `logo`, `image`, `telephone`, `address`, `locality`, `region`, `postalCode`, `mapLocation`, `socialLinks`, `sameAs`, `brand`, `siteName`, …).
Veri anahtarları: `name`, `description`, `image` (yalnız sayfada görünen görsel: kapak, ürün fotoğrafı), `parents` (Anasayfa ile sayfa arasındaki **gerçek, 200 dönen** basamaklar: `[['name'=>'Blog','url'=>…]]`), türe özgü alanlar (`headline`, `datePublished`, `dateModified`, `author` = `['name','jobTitle']` (`title` de olur: içerik servisinin `$post['author']` değeri olduğu gibi geçer; [Blog-Yazar-Kunyesi](../Services/Blog-Yazar-Kunyesi.md)), `items` = `[['name','url']]`, `price`, `currency`, `sku`, `brand`, `serviceType`, `areaServed`). Yeni türlerin alanları (FRW-30; yalnız SAYFADA GÖRÜNEN gerçek veri verilir): `newsArticle` = `blogPost` ile aynı (yazar yalnız sayfada görünüyorsa); `tvSeries` = `startDate`, `numberOfSeasons`, `numberOfEpisodes`, `genre` (ad listesi), `actor` (`[['name','url']]`); `movie` = `dateCreated`, `genre`, `director`, `actor`; `person` = `birthDate`, `deathDate`, `birthPlace`. Gün tarihleri `FormatHelper::toIsoDate()` tek kaynağından `YYYY-MM-DD` ya da `YYYY` yazılır; `datePublished`/`dateModified` `toIso8601()` ile saat dilimli. Google: `Movie` zengin sonucu yalnız karusel içindedir; `TVSeries` ve `Person` için zengin sonuç yoktur ama geçerli Schema.org düğümüdür (docs'ta bu üç tür için madde yoktur). Bu türlerde de puan yazılmaz. Düğüm `url` değeri HER ZAMAN sayfanın canonical adresidir. Breadcrumb URL yolundan TÜRETİLMEZ.
### Politika kapısı (`SchemaPolicy`) — proje ayarıyla açılamaz
- `aggregateRating`, `review` hiçbir düğümde yazılmaz (kurum kendi puanını işaretleyemez); `FAQPage`, `SearchAction`, `AggregateOffer` yazılmaz.
- `Product` yalnız `productDetail` sayfasında ve yalnız tamsa (`name`, `image`, Offer `price` > 0 + `priceCurrency`); `availability`, `shippingDetails`, `hasMerchantReturnPolicy` yalnız veri verilirse yazılır. Para birimi, stok, kargo, iade uydurulmaz.
- `TVSeries`, `Movie`, `Person` adsız yazılmaz; gün tarihi alanı `YYYY-MM-DD`/`YYYY` değilse düşer.
- BreadcrumbList en az 2 öğe; ana sayfada yok.
- Tarih ISO 8601 + saat dilimi; çözülemeyen tarih düşer; teknik güncelleme tarihi (`updated_at`) hiçbir çıktıda yok.
- `priceRange` < 100 karakter ve yalnız verilirse; `geo` en az 5 ondalık; LocalBusiness alt tipi `address` yoksa yazılmaz; telefon E.164 (`+902423225060`, `phone_e164()`); Türkiye numarası ya da `+` ile yazılmış uluslararası numara dışındaki değer düşer.
- `noindex` sayfa JSON-LD basmaz (yapısal veri içeren sayfa noindex ile engellenmez).
## 2. ``
- `canonical`: tek, mutlak, `url(path)` (sitemap/feed ile aynı yapıcı, sorgusuz); yalnız HTML ``'de.
- Open Graph: `og:title`, `og:type`, `og:image`, `og:url` zorunlu; `og:description`, `og:site_name` (`` ve `WebSite.name` ile aynı ad), `og:locale` (`DEFAULT_LANGUAGE`), `og:image:secure_url/type/width/height/alt` (dosya biliniyorsa), ``. `og:type` sayfa türünden: blog yazısı `article`. Görsel https mutlak adres.
- X (Twitter) kartı üretilmez (resmi belge okunamadı: docs DOĞRULANMADI). hreflang üretilmez (docs maddesi yok).
- Robots: HTML sayfada yalnız ``; yönergeler docs tablosundaki adlardan (`SeoResolver::robotsDirective()` bilinmeyeni düşürür). HTML sayfaya `X-Robots-Tag` başlığı YAZILMAZ (başlık yalnız HTML dışı dosyalar içindir).
- Sayfa görseli bildirimi: `SeoService::setImage($path, $alt)`, `setType($type)`; `blogPost`/`newsArticle`/`productDetail` türü bunu kendisi yapar (`newsArticle` → `og:type=article`; `tvSeries`, `movie`, `person` `website` kalır).
## 3. Bağlantı `rel`
`Core\Support\Definitions\Render\LinkRel::attr($tür, $yeniSekme)` TEK tanımdır: ödemeli/reklam → `sponsored`; yorum/kullanıcı içeriği → `ugc`; diğer ve istenmeyen (framework imza bağlantısı, paylaşım düğmeleri) → `nofollow`; editoryal (kendi sosyal profili, kardeş site) → Google niteleyicisi yok. `target="_blank"` için `noopener noreferrer` eklenir.
## 4. İzin (consent), analitik, reklam
Ölçüt: `docs/adsense/riza-cmp.md`, `docs/analytics/ga4-tuketici-onayi.md`, `docs/yasal/kvkk-web-sitesi-gereksinimleri.md`. Proje yalnız **veri** verir; kuralları framework uygular, proje KAPATAMAZ.
### 4.1 Consent Mode ve kapılı kod
- `ConsentProvider::headHtml()` her sayfada, ölçüm kodundan ÖNCE `gtag('consent','default', {4 parametre: denied})` yazar; kayıtlı seçim varsa `update` gönderir. `ad_user_data` ve `ad_personalization` framework kodunda HİÇBİR yerde `granted` yapılmaz.
- Reklam kodu (`google_adsense_code`) ve serbest `head_scripts`/`body_scripts` ayarlarının `