# Nesneler

Objects modülü, platformun genel içerik modelidir. Satıcı, client dashboard'da **nesne türleri** ("SSS", "Sayfa" veya "Mağaza lokasyonu" gibi içerik türleri) tanımlar; her türün sıralı ve tipli bir **özellik** listesi vardır. İçerik editörleri daha sonra bu türlerde **kayıtlar** (girdiler) oluşturur. Storefront'unuz her ikisini de public API üzerinden okur: tür tanımları hangi şekli beklemeniz gerektiğini söyler, kayıtlar içeriği taşır.

Bu, modülü LLM tabanlı ve headless storefront'lar için doğal bir seçim yapar: şemayı öğrenmek için `/v1/api/objects/types` endpoint'ini bir kez çağırın, ardından kayıtları genel bir şekilde render edin.

Dört endpoint'in tümü `/v1/api/objects` altında yer alır, salt okunurdur, API anahtarınızda `objects:read` scope'unu ve `objects` modülünün etkin olmasını gerektirir (aksi halde `403 {"error":"Module not enabled: objects"}`).

## Nesne türleri ve özellikler

Bir nesne türünün bir `key` değeri (URL'lerde kullanılan benzersiz bir slug; `types`, `records`, `properties` ve `bulk` değerleri rezervedir ve asla görünmez), tekil bir `name` değeri, bir `plural_name` değeri ve kayıtlarının yayınlanıp yayınlanmadığını ve nasıl adreslendiğini söyleyen `settings` değeri vardır. Her tür otomatik olarak zorunlu bir `name` metin özelliği taşır; kalanını satıcılar ekler.

Türün `settings` nesnesi:

| Alan | Tür | Açıklama |
| --- | --- | --- |
| `publishable` | boolean | Bu türün kayıtları taslak olarak başlayıp yayınlanması gerekiyorsa `true` (bkz. [Yayınlama ve görünürlük](#yaynlama-ve-grnrlk)). Taslak adımı olmayan türler için `false`. |
| `slug` | object | Yalnızca tür kayıtlarına adres veriyorsa bulunur: `{source, prefixes}`. `source`, adresin türetildiği metin özelliğinin anahtarıdır. `prefixes`, bir dil etiketini o dilin adres önekine eşler, örneğin `{"en": "/services", "tr": "/hizmetler"}`; boş string önek yok demektir. Türün adresi yoksa bulunmaz. |

Bir özellik tanımı şunları içerir:

| Alan | Tür | Açıklama |
| --- | --- | --- |
| `key` | string | `/^[a-z][a-z0-9_]*$/` desenine uyan makine anahtarı. Kayıtların `values` alanında kullanılan anahtar budur. |
| `label` | string | İnsan tarafından okunan etiket. |
| `type` | string | Aşağıdaki özellik türlerinden biri. |
| `options` | array of string or null | `select` ve `token_variant` özellikleri için izin verilen değerler; diğer tüm türler için `null`. |
| `localized` | boolean | Değer her içerik dili için ayrı saklanıyorsa `true` (bkz. Yerelleştirilmiş değerler). |
| `config` | object or null | Türe özgü yapılandırma: `repeater` için `{fields, item_label_field}`, `record_ref` ve `record_ref_list` için `{object_type_keys}`. Diğer türler için `null`. |
| `is_required` | boolean | Özelliğin bir değere sahip olmasının zorunlu olup olmadığı. Yerelleştirilmiş bir özellik için bu, varsayılan dilde bir değer demektir. |
| `position` | integer | Tür içindeki sıralama pozisyonu, 0 tabanlı. |

Özellik türleri ve her birinin `values` içinde ürettiği değer. Aynı türler section ve repeater satırlarındaki alanlar için de kullanılabilir.

| Tür | `values` içindeki değer | Kısıtlamalar |
| --- | --- | --- |
| `text` | string | En fazla 255 karakter. |
| `textarea` | string | En fazla 10000 karakter. |
| `richtext` | string (HTML) | En fazla 50000 karakter. Sunucu tarafında `p`, `br`, `strong`, `em`, `ul`, `ol`, `li`, `a[href]`, `img[src, alt]`, `h2`, `h3`, `h4` olacak şekilde temizlenir. Temizlemeden yalnızca `https://`, `http://`, kök göreli `/`, `mailto:` ve `tel:` href'leri sağ çıkar. Bir `img` yalnızca `src` ve `alt` özelliklerini korur; `src` `https://` veya kök göreli `/` değilse kaldırılır. |
| `number` | number | Tamsayı veya ondalıklı. |
| `money` | integer | Negatif olmayan, cent cinsinden. `15900`, mağaza para biriminde 159,00 anlamına gelir. |
| `boolean` | boolean | |
| `select` | string | Özelliğin `options` değerlerinden biri. |
| `date` | string | `YYYY-MM-DD`. |
| `datetime` | string | Offset içeren ISO 8601, örneğin `2026-10-12T10:00:00+02:00`. |
| `customer` | string (uuid) | Bir müşteri id'si. |
| `media` | object or null | Herkese açık bir medya kütüphanesi öğesinin `{id, url, alt, width, height, mime_type}` değeri; bkz. Medya değerleri. |
| `media_list` | array of object | En fazla 50 medya nesnesi, her biri fazladan bir `caption` ile; bkz. Medya değerleri. |
| `link` | object `{url, label}` | `url` zorunlu, en fazla 2000 karakter, richtext href'leriyle aynı şema izin listesi; `label` isteğe bağlı, en fazla 200 karakter. |
| `icon` | string | `/^[a-z][a-z0-9-]{0,39}$/` desenine uyan ikon adı. |
| `token_variant` | string | Özelliğin `options` değerlerinden biri. |
| `color` | string | `#RRGGBB`, örneğin `#1A2B3C`. |
| `email` | string | Geçerli bir e-posta adresi, en fazla 255 karakter. |
| `phone` | string | 5 ile 30 karakter: rakamlar, boşluklar, `()-.`, başta isteğe bağlı bir `+`. |
| `tags` | array of string | 1 ile 60 karakter arası en fazla 50 etiket, tekrarlar kaldırılır. |
| `record_ref` | string (uuid) | Özelliğin `config.object_type_keys` türlerinden birindeki başka bir kaydın id'si. `GET /v1/api/objects/records/{id}` ile getirin. |
| `record_ref_list` | array of string (uuid) | Diğer kayıtlara referanslar; en fazla 24 öğe. |
| `repeater` | array of row objects | Her satır `{"_key": "row_{24 hex}", ...alanlar}` şeklindedir; alanlar özelliğin `config.fields` değerinde tanımlıdır. En fazla 50 satır. Bir satır, satırları repeater içermeyen bir repeater daha tutabilir ve bir repeater'da en fazla 40 alan bulunur. Repeater'ın kendisi yerelleştirilemez, alanları yerelleştirilebilir. |
| `sections` | array | Yapılandırılmış sayfa oluşturucu (page-builder) içeriği; aşağıya bakın. |

Özellikler dashboard'da arşivlenebilir. Arşivlenmiş özellikler public API'da görünmez: türün özellik listesinden çıkarılır ve anahtarları kayıtların `values` alanından temizlenir.

## Kayıtlar

Bir kayıt `{id, values, published_at, created_at}` yapısındadır; türün adresleri varsa ayrıca `slugs` içerir. `values`, özellik anahtarıyla anahtarlanmış bir JSON nesnesidir. Değeri olmayan özellikler `values` içinde hiç bulunmaz (null değerler kaydetme sırasında atılır), bu yüzden eksik anahtarları her zaman "değer yok" olarak ele alın. Tek istisna, eksik veya özel bir öğeyi gösteren `media` değeridir: bu anahtar `null` değeriyle bulunur. `published_at` ve `created_at` ISO 8601 zaman damgalarıdır; `published_at`, kaydın yayına girdiği andır (yayınlanabilir olmayan bir tür için oluşturulma zamanıdır).

`slugs`, bir dil etiketini kaydın o dildeki adresine eşler, örneğin `{"en": "kitchen-fitting", "tr": "mutfak-montaji"}`. Slug, yolun son bölümüdür: storefront'unuzdaki tam yol, türün o dil için öneki (`settings.slug.prefixes` içinden) artı `/` artı slug'dır. Yalnızca etkin içerik dilleri görünür. Bir kaydı adresiyle `GET /v1/api/objects/types/{key}/records/by-slug/{slug}` ile arayın (bkz. [Kayıtlar](./records)).

## Yayınlama ve görünürlük

Public API yalnızca satıcının yayınladığı içeriği sunar.

- `settings.publishable: true` olan bir türde, bir kayıt yayınlanmış ve `published_at` değeri şimdi veya geçmişteyse görünürdür. Taslaklar ve gelecekteki bir `published_at` için zamanlanmış kayıtlar listeden çıkarılır ve tek kayıt endpoint'lerinin ikisinde de `404` döndürür. Zamanlanmış bir kayıt zamanı geldiğinde kendiliğinden görünür; o anda hiçbir webhook gönderilmez.
- Yayınlanabilir olmayan bir türde kayıtların taslak adımı yoktur ve oluşturulduğu anda görünürdür. (Yayınlama kapatılmadan önce kalmış taslaklar gizli kalır.)
- Görünürlük her endpoint'te aynıdır. `filter[status]` public API'da kullanılamaz (`422` döndürür), çünkü okuyabildiğiniz her kayıt zaten yayınlanmıştır.

## Yerelleştirilmiş değerler

`localized` olarak işaretlenen bir özellik veya section alanı, her içerik dili için ayrı bir değer saklar. `values` içindeki değeri, dil etiketinden değere bir haritadır: `{"en": "Hello", "tr": "Merhaba"}`; etiketler `/^[a-z]{2}(-[A-Z]{2})?$/` desenine uyar. API haritayı mağaza için o anda etkin olan dillere indirger; böylece satıcının sonradan kapattığı bir dil asla sızmaz. Satıcının boş bıraktığı bir dil haritada hiç bulunmaz: mağazanın varsayılan diline dönün; bu dil her zaman ilk etkin dildir ve özellik zorunluysa her zaman doludur. Zorunlu olmayan bir değerin varsayılan dil için girdisi olmayabilir, örneğin varsayılan dili `en` olan bir mağazada `{"nl": "Hallo"}`; map içinde etkin dil kalmazsa değer `null` olur.

`localized` olmayan bir özellik, türü ne olursa olsun her zaman düz bir değer döndürür. Number, money, boolean, date, datetime, customer, color, media_list, kayıt referansları, repeater ve sections özellikleri yerelleştirilemez (bir repeater satırındaki veya bir section içindeki alanlar yerelleştirilebilir). Aynı tür için iki şekli de işleyin, çünkü satıcı bir özelliği sonradan yerelleştirebilir.

## Medya değerleri

`media` ve `media_list` değerleri sizin için çözümlenir; böylece storefront'un ikinci bir isteğe ihtiyacı olmaz:

```json title="media value"
{
  "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
  "url": "https://cdn.borkol.com/t/abc/hero.webp",
  "alt": "Oak table in a sunny room",
  "width": 1600,
  "height": 900,
  "mime_type": "image/webp"
}
```

| Alan | Tür | Açıklama |
| --- | --- | --- |
| `id` | string (uuid) | Medya kütüphanesi id'si. |
| `url` | string | Dosyanın herkese açık URL'si. |
| `alt` | string or null | Medya kütüphanesindeki alternatif metin. |
| `width`, `height` | integer or null | Piksel boyutu; bilinmiyorsa `null` (örneğin görsel olmayan dosyalar için). |
| `mime_type` | string | Örneğin `image/webp`. |

Bir `media` değeri bu nesnedir; öğe artık yoksa veya özelse `null` olur. Bir `media_list` değeri bu nesnelerin listesidir, her biri fazladan bir `caption` taşır (`string`, bir locale haritası veya `null`); bir öğe, kütüphanedeki alt metnin yerine geçen kendi `alt` değerini taşıyabilir (bir string veya locale haritası). Eksik veya özel öğeler listeden çıkarılır, bu yüzden liste satıcının seçtiğinden kısa olabilir. Yalnızca herkese açık medya sunulur; özel dosyalar asla görünmez.

## Sections değerleri

`sections` türündeki bir özellik sayfa oluşturucu içeriği tutar: değeri bir **section örneği listesidir**. Boş olarak saklanmış bir sections değeri `[]` döndürür. Her örnek şu şekildedir:

```json title="Section instance"
{
  "_key": "sec_a1b2c3d4e5f60718293a4b5c",
  "type": "hero",
  "look": "default",
  "v": 1,
  "visible": true,
  "data": { "title": { "en": "Welcome" }, "cta": { "url": "/products", "label": "Shop now" } }
}
```

| Alan | Tür | Açıklama |
| --- | --- | --- |
| `_key` | string | Kararlı örnek anahtarı, `sec_` artı 24 hex karakter. |
| `type` | string | Client dashboard'da mağaza bazında tanımlanan section türü anahtarı. |
| `look` | string | O section türünün görsel varyant (look) anahtarı. |
| `v` | integer | Kaydetme anındaki section türünün şema sürümü. |
| `visible` | boolean | Editörler bir section'ı silmeden gizleyebilir. Render ederken `visible: false` olan örnekleri atlayın. |
| `data` | object | Section türünün alan anahtarlarıyla anahtarlanmış alan değerleri. |

Section örnekleri, yazma sırasında mağazanın section türü tanımlarına (anahtar, ad, ikon, look'lar, şema sürümü, alanlar, öğe etiket alanı) göre doğrulanır; bu tanımlar client dashboard'da yönetilir. Public API section türü tanımlarını sunmaz; storefront'unuz ve satıcı, section sözlüğü üzerinde harici olarak anlaşır.

Yukarıdaki özellik tablosundaki her alan türü, aynı değer şekli ve aynı public serileştirmeyle `data` içinde görünebilir: `media` ve `media_list` değerleri medya nesneleridir, yerelleştirilmiş alanlar etkin dillere indirgenmiş locale haritalarıdır ve repeater satırları `_key` değerlerini korur. Türü artık mağazada bulunmayan bir section listeden çıkarılır. `visible: false` olan section'lar yine de döndürülür; render ederken atlayın.

**Limitler.** Bir section en fazla 40 alan içerir. Bir sections özelliği en fazla 100 section (veya özelliğin yapılandırılmış maksimumu) ve en fazla 256KB JSON tutar.

## Kurallar

- Tüm id'ler UUID'dir. Tüm veriler, API anahtarı üzerinden örtük olarak mağazanıza kapsamlanır.
- Para her zaman tamsayı cent'tir. `date` alanlarındaki ve aralık filtrelerindeki tarihler `YYYY-MM-DD` metinleridir. `created_at` ve `published_at` zaman damgaları ISO 8601'dir.
- Yalnızca kayıt listeleme endpoint'i sayfalanır; tür listesi düz bir `data` dizisi döndürür.

## Endpoint'ler

| Endpoint | Amaç |
| --- | --- |
| `GET /v1/api/objects/types` | Özellik tanımlarıyla birlikte tüm nesne türlerini listeler. Bkz. [Türler](./types). |
| `GET /v1/api/objects/types/{key}/records` | Bir tür için sayfalanmış, filtrelenebilir kayıt listesi. Bkz. [Kayıtlar](./records). |
| `GET /v1/api/objects/types/{key}/records/by-slug/{slug}` | Tek bir kaydı, bir dildeki adresiyle getirir. Bkz. [Kayıtlar](./records). |
| `GET /v1/api/objects/records/{id}` | Tek bir kaydı id ile getirir. Bkz. [Kayıtlar](./records). |
