# Yapılandırma şeması

Şema endpoint'i, bir storefront'un tek bir ürün için konfigüratör arayüzü oluşturmak üzere ihtiyaç duyduğu her şeyi döndürür: seçim bazlı aralık kısıtlarıyla birlikte boyutlar, ürünün fiyat matrisleri (hangi matrisin geçerli olduğunu göstermek için) ve seçimleri, fiyat deltaları, seçimler arası kuralları, görselleri ve `requires_quote` bayraklarıyla birlikte seçenek grupları. Bu kavramların birbirine nasıl bağlandığını görmek için bölüm girişine bakın.

## GET /v1/api/commerce/configurator/products/{id}/schema

Aktif, yapılandırılabilir tek bir ürünün eksiksiz yapılandırma şemasını döndürür. Response'taki her şey, o an kullanılabilir olan seçimlere göre budanmıştır: bir seçim yalnızca aktifse, silinmemişse ve her `requires` hedef grubu hâlâ en az bir kullanılabilir seçim içeriyorsa görünür (budama zincirleme ilerler, dolayısıyla kullanılabilir olmayan bir seçimi gerektiren seçim de kaybolur). Boyut kısıtları ile `requires` ve `excludes` listeleri yalnızca bu kullanılabilir seçim ID'lerine referans verir; kullanılabilir olmayan bir seçime koşullanmış fiyat matrisi ise `price_matrices` içinden tamamen çıkarılır. Hem `status = active` hem de `capability = made_to_measure` olmayan her ürün için 404 döndürür.

### Yol parametreleri

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| id | string (uuid) | Evet | Ürün ID'si. Capability değeri `made_to_measure` olan aktif bir ürün olmalıdır. |

### Yanıt alanları

`data` nesnesinin üç anahtarı vardır.

**data.dimensions** (dizi, pozisyon sırasına göre; sıra, fiyat matrisi eksenleri `dim1` ve `dim2` ile eşlemeyi belirler):

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| key | string | her zaman | Quote çağrılarında bu boyut için kullanılacak request anahtarı. |
| label | string | her zaman | Görüntüleme etiketi. |
| unit | string | her zaman | Görüntüleme birimi metni, örneğin `"cm"`. |
| min | integer | her zaman | Kısıt daraltmasından önce izin verilen en düşük değer. |
| max | integer | her zaman | Kısıt daraltmasından önce izin verilen en yüksek değer. |
| constraints | array | her zaman | Seçim bazlı aralık daraltmaları; hiç yoksa boş dizi. Her öğe: `choice_id` (uuid), `min` (integer veya null), `max` (integer veya null). İlgili seçim seçildiğinde, null olmayan bir `min` geçerli alt sınırı yükseltir ve null olmayan bir `max` geçerli üst sınırı düşürür. |

**data.price_matrices** (dizi, oluşturulma sırasına göre):

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| id | string (uuid) | her zaman | Matris ID'si. Bu matris taban fiyatı sağladığında quote endpoint'i tarafından `matrix.id` olarak geri döndürülür. |
| name | string | her zaman | Matris adı. |
| conditions | array of string (uuid) | her zaman | Matrisin uygun sayılması için tümünün seçili olması gereken seçim ID'leri. Boş dizi her zaman uygun anlamına gelir. Uygun matrisler arasında en fazla koşula sahip olan kazanır. Kullanılabilir olmayan bir seçime koşullanmış matrisler hiç listelenmez, dolayısıyla bu dizi, motorun gerektirdiğine kıyasla asla kısaltılmaz. |

**data.option_groups** (dizi, pozisyon sırasına göre):

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| id | string (uuid) | her zaman | Grup ID'si. |
| name | string | her zaman | Grup adı. Quote döküm etiketlerinin ön eki olarak da kullanılır (`"Group: Choice"`). |
| type | string | her zaman | `single` (en fazla bir seçim yapılabilir) veya `multi` (istenildiği kadar). |
| required | boolean | her zaman | Bu gruptan en az bir seçim yapılmasının zorunlu olup olmadığı. |
| choices | array | her zaman | Pozisyon sırasına göre seçimler, aşağıya bakın. |

**data.option_groups[].choices[]**:

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| id | string (uuid) | her zaman | Seçim ID'si. Quote request'inin `choices` dizisinde bunu gönderin. |
| name | string | her zaman | Seçim adı. |
| delta_type | string | her zaman | `fixed`, `per_area`, `percent` veya `percent_of_total`. |
| delta_value | integer | her zaman | `fixed` için küçük birim; `per_area` için metrekare başına küçük birim; `percent` ve `percent_of_total` için yüzde çarpı 100 (1050 = yüzde 10,50). |
| is_default | boolean | her zaman | İlk seçim için arayüz ipucu. |
| requires | array of string (uuid) | her zaman | Bu seçimin gerektirdiği seçim ID'leri. Tek bir hedef grubu içinde OR, hedef grupları arasında AND. |
| excludes | array of string (uuid) | her zaman | Bu seçimle birleştirilemeyen seçim ID'leri. |
| images | array | her zaman | `[{url, alt}]`; seçimin medyası yoksa boş dizi. |
| requires_quote | boolean | her zaman | `true` olduğunda storefront, alıcıyı ödeme (checkout) yerine manuel teklif talebine yönlendirmelidir. Bilgilendirme amaçlıdır: quote endpoint'i yapılandırmayı yine de fiyatlar. |

```bash title="Request"
curl "https://api.borkol.com/v1/api/commerce/configurator/products/9c2f1e6a-8b4d-4f2a-9e11-3d5a7b9c0e21/schema" \
  -H "Authorization: Bearer {api_key}" \
  -H "Accept: application/json"
```

```javascript title="Request (JS)"
const res = await fetch(
  `https://api.borkol.com/v1/api/commerce/configurator/products/${productId}/schema`,
  {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      Accept: "application/json",
    },
  }
);
const { data } = await res.json();
```

```json title="Response"
{
  "data": {
    "dimensions": [
      {
        "key": "width",
        "label": "Width",
        "unit": "cm",
        "min": 200,
        "max": 700,
        "constraints": [
          {
            "choice_id": "c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
            "min": null,
            "max": 600
          }
        ]
      },
      {
        "key": "depth",
        "label": "Depth",
        "unit": "cm",
        "min": 150,
        "max": 400,
        "constraints": []
      }
    ],
    "price_matrices": [
      {
        "id": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a",
        "name": "Glass roof",
        "conditions": ["c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c"]
      },
      {
        "id": "e5f6a7b8-c9d0-4e1f-a2b3-c4d5e6f7a8b9",
        "name": "Base",
        "conditions": []
      }
    ],
    "option_groups": [
      {
        "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
        "name": "Roof type",
        "type": "single",
        "required": true,
        "choices": [
          {
            "id": "c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
            "name": "Glass",
            "delta_type": "fixed",
            "delta_value": 0,
            "is_default": true,
            "requires": [],
            "excludes": ["f6a7b8c9-d0e1-4f2a-b3c4-d5e6f7a8b9c0"],
            "images": [
              {
                "url": "https://cdn.borkol.com/t/9c2f/glass-roof.jpg",
                "alt": "Glass roof"
              }
            ],
            "requires_quote": false
          }
        ]
      },
      {
        "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
        "name": "LED lighting",
        "type": "multi",
        "required": false,
        "choices": [
          {
            "id": "f6a7b8c9-d0e1-4f2a-b3c4-d5e6f7a8b9c0",
            "name": "LED set (6)",
            "delta_type": "per_area",
            "delta_value": 2500,
            "is_default": false,
            "requires": ["c1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c"],
            "excludes": [],
            "images": [],
            "requires_quote": false
          }
        ]
      }
    ]
  }
}
```

### Hatalar

| Durum | Gövde | Neden |
| --- | --- | --- |
| 401 | `{"message":"Unauthenticated."}` | Eksik veya geçersiz API anahtarı. |
| 403 | `{"message":"Invalid ability provided."}` | Anahtarda ne `catalog:read` ne de `commerce:read` scope'u var. |
| 403 | `{"error":"Module not enabled: configurator"}` | Tenant'ta configurator modülü etkin değil. `message` yerine `error` anahtarına dikkat edin. |
| 403 | `{"message":"Tenant suspended.","code":"tenant_suspended"}` | Tenant hesabı askıya alınmış. |
| 404 | `{"message":"..."}` | Ürün mevcut değil, aktif değil veya capability değeri `made_to_measure` değil. |
| 429 | `{"message":"Too Many Attempts."}` | Dakikada 120 request'lik rate limit aşıldı. |
