{
  "openapi": "3.1.0",
  "info": {
    "title": "UstaGeliyor Partner API",
    "version": "1.0.0",
    "description": "Üçüncü taraf sistemlerin (e-ticaret altyapıları, özel yazılımlar) ve ustaların UstaGeliyor'da **müşteri** ya da **usta** olarak iş açtığı, izlediği ve yürüttüğü API.\n\n## Kimlik doğrulama\nHer istek `Authorization: Bearer ugp_…` taşır. Anahtarı UstaGeliyor operasyon ekibi bir hesap adına üretir; sır yalnızca üretildiği anda bir kez gösterilir. Anahtar:\n- **bir hesaba** bağlıdır — her çağrı o hesap adına yapılır;\n- **bir rol** taşır: `customer` ya da `usta` (`x-ug-role` başlığı gönderilmez, yok sayılır);\n- **izinler (scope)** taşır: `read` (her GET), `write` (para hareket ettirmeyen durum değişimi), `money` (ödeme açma, onay, iade, itiraz, teklif/ek iş kabulü, hakediş onayı).\n\nGeçersiz, iptal edilmiş ve süresi dolmuş anahtarlar aynı cevabı alır: 401 `PARTNER_KEY_INVALID`.\n\n## Hata biçimi\nBaşarısız her yanıt `{ \"message\": \"…\", \"code\": \"…\" }` taşır. Dallanmayı **`code`** ile yapın; mesajlar değişebilir. Doğrulama hataları 400 `VALIDATION_ERROR` ve `issues` listesiyle gelir.\n\n## Hız sınırı\nAnahtar başına dakikada 120 istek (anahtara özel değer verilebilir). Her yanıtta `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`; aşılınca 429 `RATE_LIMITED` ve `Retry-After`.\n\n## Tutarlar\nBütün tutarlar **tam Türk lirası** (750 = ₺750). Fiyat ve başlık hiçbir zaman istemciden alınmaz; katalogdan hesaplanır.\n\n## Kart ödemesi\nHam kart bilgisi bu API'den geçmez. `POST /payments` kart için `payment.payment_url` döner: müşteriyi o adrese (tarayıcı ya da WebView) yönlendirin, 3D Secure bankanın sayfasında tamamlanır ve ödeme bankanın onayıyla tutulur. Havale için talimatlar (`reference`, `amount`, `accounts`) döner. Barındırılan sayfa bankaya bağlanana kadar gerçek kart ödemesi açık bir ortamda kart isteği `503 HOSTED_PAYMENT_UNAVAILABLE` alır ve hiçbir ödeme kaydı açılmaz.\n\n## Tekrar gönderim\nv1'de `Idempotency-Key` yok. Aynı rezervasyonu iki kez açmak 409 `SLOT_CONFLICT`, aynı talebe ikinci ödeme 409 `ESCROW_EXISTS` ile durur.\n\n## İzleme\n`X-Request-Id` gönderirseniz aynen geri döner; göndermezseniz biz üretiriz. Destek isterken bu değeri paylaşın.",
    "contact": {
      "name": "UstaGeliyor",
      "url": "https://ustageliyor.com"
    }
  },
  "servers": [
    {
      "url": "https://panel.ustageliyor.com/partner/v1",
      "description": "Partner API v1"
    }
  ],
  "security": [
    {
      "PartnerKey": []
    }
  ],
  "tags": [
    {
      "name": "Katalog",
      "description": "Hizmetler, fiyatlar, randevu saatleri, sözleşmeler ve ödeme yöntemleri."
    },
    {
      "name": "Hesap",
      "description": "Anahtarın hesabı, bildirimler ve dosya yükleme."
    },
    {
      "name": "Rezervasyonlar",
      "description": "Müşteri olarak iş açmak, izlemek, iptal istemek ve onaylamak."
    },
    {
      "name": "Ödemeler",
      "description": "Rezervasyonun ödemesi (kart: barındırılan sayfa, havale: talimat), iade isteği ve itiraz."
    },
    {
      "name": "Ek iş",
      "description": "Ustanın iş başında çıkardığı ek ücret talepleri ve pazarlığı."
    },
    {
      "name": "Teklifler",
      "description": "Keşifli işlerde ustanın teklifi ve müşterinin kararı."
    },
    {
      "name": "Sohbet",
      "description": "Talep başına müşteri–usta mesajlaşması; yeni mesajlar `after` ile yoklanır."
    },
    {
      "name": "Destek",
      "description": "Destek talepleri (iptal isteği dahil)."
    },
    {
      "name": "Usta — İşler",
      "description": "Usta olarak iş havuzu, kabul, yola çıkma, başlatma ve tamamlama."
    },
    {
      "name": "Usta — Dükkân",
      "description": "Usta profili, çalışma saatleri, belgeler ve kayıt durumu."
    },
    {
      "name": "Usta — Hakediş",
      "description": "Haftalık hakediş dökümleri ve ustanın onayı."
    },
    {
      "name": "Meta",
      "description": "Makinenin okuyacağı API tanımı."
    }
  ],
  "x-tagGroups": [
    {
      "name": "Müşteri",
      "tags": [
        "Katalog",
        "Hesap",
        "Rezervasyonlar",
        "Ödemeler",
        "Ek iş",
        "Teklifler",
        "Sohbet",
        "Destek"
      ]
    },
    {
      "name": "Usta",
      "tags": [
        "Usta — İşler",
        "Usta — Dükkân",
        "Usta — Hakediş"
      ]
    },
    {
      "name": "Meta",
      "tags": [
        "Meta"
      ]
    }
  ],
  "paths": {
    "/appointment-slots": {
      "get": {
        "operationId": "listAppointmentSlots",
        "tags": [
          "Katalog"
        ],
        "summary": "Randevu dilimlerini listele",
        "description": "Bir günün randevu dilimleri ve doluluk. `POST /bookings` isteğinin `appointment_slot` değeri buradaki `slot`.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Gün, `YYYY-MM-DD`.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "date": {
                      "type": "string"
                    },
                    "slots": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "slot": {
                            "type": "string"
                          },
                          "available": {
                            "type": "boolean"
                          },
                          "label": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "slot",
                          "available",
                          "label"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "date",
                    "slots"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/bookings": {
      "get": {
        "operationId": "listBookings",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Rezervasyonları listele",
        "description": "Anahtarın hesabının rezervasyonları, en yeni önce; atanan ustanın özeti ve grup kardeşleriyle. Ödemesi hiç başlamamış sabit fiyatlı taslaklar listelenmez.\n\n**Erişim:** müşteri anahtarı · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requests": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "reference": {
                            "description": "Müşteriye ve ekibe gösterilen talep numarası (`UG-102609123456`).",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "status": {
                            "type": "string"
                          },
                          "amount": {
                            "description": "Sunucunun hesapladığı tutar, tam TL.",
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "appointment_date": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "appointment_slot": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "group_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "status",
                          "amount",
                          "appointment_date",
                          "appointment_slot"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "role": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "requests",
                    "role"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "requests": [],
                  "role": "customer"
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "createBooking",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Rezervasyon oluştur",
        "description": "Anahtarın hesabı adına bir iş açar. Fiyat ve başlık katalogdan hesaplanır; il/ilçe kapsamda değilse 422 `SERVICE_AREA_NOT_COVERED`. Sepet birden fazla mesleğe yayılıyorsa her meslek ayrı bir talep (bacak) olur ve `group_id` ile bağlanır. Talep ödeme alınana kadar ustaya gitmez: ardından her bacak için `POST /payments`.\n\n**Erişim:** müşteri anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "description": "Seçilen hizmetler. Başlık ve fiyat istemciden alınmaz; farklı mesleklere yayılan bir sepet her meslek için ayrı bir talebe (bacağa) bölünür.",
                    "minItems": 1,
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "variant_id": {
                          "description": "Paket (varyant) kimliği. Verilmezse hizmetin en ucuz paketi.",
                          "type": "string",
                          "minLength": 1
                        },
                        "product_id": {
                          "description": "Hizmet (ürün) kimliği; `variant_id` yoksa zorunlu.",
                          "type": "string",
                          "minLength": 1
                        },
                        "quantity": {
                          "description": "Adet, 1–99. Varsayılan 1.",
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 99
                        },
                        "answers": {
                          "description": "Hizmet sorularının cevapları (`ug_service_questions`). Fiyat farkı katalogdan hesaplanır, istemciden gelmez; zorunlu soru boşsa 400 `INVALID_SERVICE_ANSWER`.",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "question_id": {
                                "description": "Sorunun kimliği.",
                                "type": "string",
                                "minLength": 1
                              },
                              "option_ids": {
                                "description": "Seçim sorularında işaretlenen seçenekler.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "text": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "number": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "photos": {
                                "description": "Fotoğraf sorusu: `POST /uploads/photo` adresleri.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "entry_id": {
                                "description": "Katalog sorusu (marka/model): `GET /reference-catalogs/{key}` girdisinin kimliği.",
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "entry_label": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "question_id"
                            ]
                          }
                        }
                      }
                    }
                  },
                  "appointment_date": {
                    "description": "Randevu günü, `YYYY-MM-DD`.",
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "appointment_slot": {
                    "description": "Randevu dilimi, `GET /appointment-slots` cevabındaki `slot` (ör. `09:00-11:00`).",
                    "type": "string",
                    "minLength": 1
                  },
                  "city": {
                    "description": "İl, ör. `İstanbul`. Kapsam ve bölge fiyatı buna göre.",
                    "type": "string",
                    "minLength": 1
                  },
                  "district": {
                    "description": "İlçe, ör. `Kadıköy`.",
                    "type": "string",
                    "minLength": 1
                  },
                  "address_summary": {
                    "description": "Ustanın gideceği açık adres (cadde, numara, daire).",
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 500
                  },
                  "notes": {
                    "description": "Müşterinin işi anlatan notu.",
                    "type": "string",
                    "maxLength": 2000
                  },
                  "photos": {
                    "description": "`POST /uploads/photo` ile yüklenmiş dosya adresleri (en çok 5). Bu sunucunun üretmediği adresler sessizce düşürülür.",
                    "anyOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      {
                        "type": "string"
                      }
                    ]
                  },
                  "latitude": {
                    "description": "Adresin enlemi.",
                    "type": "number",
                    "minimum": -90,
                    "maximum": 90
                  },
                  "longitude": {
                    "description": "Adresin boylamı.",
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180
                  },
                  "billing": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "description": "`corporate` kurumsal fatura demek; diğer alanlar yalnızca o zaman okunur.",
                        "type": "string",
                        "enum": [
                          "individual",
                          "corporate"
                        ]
                      },
                      "tax_id": {
                        "description": "VKN (10) ya da TCKN (11 hane).",
                        "type": "string"
                      },
                      "tax_office": {
                        "type": "string"
                      },
                      "company": {
                        "type": "string"
                      },
                      "e_invoice": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "type"
                    ]
                  },
                  "legal_acceptance": {
                    "type": "object",
                    "properties": {
                      "documents": {
                        "description": "Müşterinin okuduğu sözleşmelerin anahtarı ve sürümü (`GET /legal`). Okunduktan sonra yeni sürüm yayınlandıysa 409 `LEGAL_VERSION_CHANGED`.",
                        "minItems": 1,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "version": {
                              "type": "integer",
                              "minimum": 1
                            }
                          },
                          "required": [
                            "key",
                            "version"
                          ]
                        }
                      },
                      "payment_method": {
                        "type": "string",
                        "enum": [
                          "card",
                          "bank_transfer"
                        ]
                      }
                    },
                    "required": [
                      "documents"
                    ]
                  }
                },
                "required": [
                  "items",
                  "appointment_date",
                  "appointment_slot",
                  "city",
                  "district",
                  "address_summary"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "description": "İlk bacak (tek meslekli sepette rezervasyonun kendisi).",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "reference": {
                          "description": "Müşteriye ve ekibe gösterilen talep numarası (`UG-102609123456`).",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "status": {
                          "type": "string"
                        },
                        "amount": {
                          "description": "Sunucunun hesapladığı tutar, tam TL.",
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "group_id": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    },
                    "requests": {
                      "description": "Bütün bacaklar; her biri için ayrı ödeme açılır.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "reference": {
                            "description": "Müşteriye ve ekibe gösterilen talep numarası (`UG-102609123456`).",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "status": {
                            "type": "string"
                          },
                          "amount": {
                            "description": "Sunucunun hesapladığı tutar, tam TL.",
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "appointment_date": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "appointment_slot": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "group_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "status",
                          "amount",
                          "appointment_date",
                          "appointment_slot"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "group_id": {
                      "description": "Birden fazla meslek varsa bacakları birleştiren kimlik, yoksa `null`.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "request",
                    "requests",
                    "group_id"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "customer_id": "cus_01J00000000000000000000000",
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "unit_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "variant_id": "variant_01J00000000000000000000000",
                        "base_price": 750
                      }
                    ],
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "title": "Klima Bakımı — Standart",
                    "notes": null,
                    "status": "pending",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "amount": 750,
                    "currency_code": "try",
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "address_summary": "Test Sok. 1 D:2",
                    "assigned_usta_id": null,
                    "cart_id": null,
                    "order_id": null,
                    "cancelled_at": null,
                    "cancel_reason": null,
                    "cancelled_by": null,
                    "metadata": {
                      "ug_fixed_price_checkout": true,
                      "ug_pricing_type": "fixed",
                      "city": "İstanbul",
                      "district": "Kadıköy"
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  },
                  "requests": [
                    {
                      "id": "01J00000000000000000000000",
                      "reference": "UG-102610123456",
                      "customer_id": "cus_01J00000000000000000000000",
                      "product_id": "prod_01J00000000000000000000000",
                      "variant_id": "variant_01J00000000000000000000000",
                      "items": [
                        {
                          "title": "Klima Bakımı — Standart",
                          "quantity": 1,
                          "unit_price": 750,
                          "product_id": "prod_01J00000000000000000000000",
                          "variant_id": "variant_01J00000000000000000000000",
                          "base_price": 750
                        }
                      ],
                      "category_handle": "klima",
                      "group_id": null,
                      "group_order": null,
                      "title": "Klima Bakımı — Standart",
                      "notes": null,
                      "status": "pending",
                      "pricing_type": "fixed",
                      "fixed_price_checkout": true,
                      "amount": 750,
                      "currency_code": "try",
                      "appointment_date": "2026-10-06",
                      "appointment_slot": "09:00-11:00",
                      "address_summary": "Test Sok. 1 D:2",
                      "assigned_usta_id": null,
                      "cart_id": null,
                      "order_id": null,
                      "cancelled_at": null,
                      "cancel_reason": null,
                      "cancelled_by": null,
                      "metadata": {
                        "ug_fixed_price_checkout": true,
                        "ug_pricing_type": "fixed",
                        "city": "İstanbul",
                        "district": "Kadıköy"
                      },
                      "created_at": "2026-10-01T09:00:00.000Z",
                      "updated_at": "2026-10-01T09:00:00.000Z",
                      "deleted_at": null
                    }
                  ],
                  "group_id": null
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `APPOINTMENT_REQUIRED` — Randevu günü ve dilimi zorunlu.\n- `INVALID_SERVICE_ANSWER` — Hizmet sorularının cevabı eksik ya da geçersiz; ayrıntı `errors` alanında.\n- `INVALID_SERVICE_ITEM` — Hizmet bulunamadı ya da yayında değil.\n- `LOCATION_REQUIRED` — İl/ilçe bilgisi eksik.\n- `ADDRESS_REQUIRED` — Hizmetin yapılacağı adres zorunlu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "APPOINTMENT_REQUIRED": {
                    "value": {
                      "message": "Randevu günü ve dilimi zorunlu.",
                      "code": "APPOINTMENT_REQUIRED"
                    }
                  },
                  "INVALID_SERVICE_ANSWER": {
                    "value": {
                      "message": "Hizmet sorularının cevabı eksik ya da geçersiz; ayrıntı `errors` alanında.",
                      "code": "INVALID_SERVICE_ANSWER"
                    }
                  },
                  "INVALID_SERVICE_ITEM": {
                    "value": {
                      "message": "Hizmet bulunamadı ya da yayında değil.",
                      "code": "INVALID_SERVICE_ITEM"
                    }
                  },
                  "LOCATION_REQUIRED": {
                    "value": {
                      "message": "İl/ilçe bilgisi eksik.",
                      "code": "LOCATION_REQUIRED"
                    }
                  },
                  "ADDRESS_REQUIRED": {
                    "value": {
                      "message": "Hizmetin yapılacağı adres zorunlu.",
                      "code": "ADDRESS_REQUIRED"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `SLOT_CONFLICT` — Bu gün ve saatte çakışan bir randevu var.\n- `LEGAL_VERSION_CHANGED` — Sözleşmenin yeni sürümü yayınlandı; güncel metin okunup yeniden onaylanmalı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "SLOT_CONFLICT": {
                    "value": {
                      "message": "Bu gün ve saatte çakışan bir randevu var.",
                      "code": "SLOT_CONFLICT"
                    }
                  },
                  "LEGAL_VERSION_CHANGED": {
                    "value": {
                      "message": "Sözleşmenin yeni sürümü yayınlandı; güncel metin okunup yeniden onaylanmalı.",
                      "code": "LEGAL_VERSION_CHANGED"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "İşlenemeyen istek.\n\n- `SERVICE_AREA_NOT_COVERED` — Bu hizmet bu bölgede verilmiyor; kapsam dışı hizmetler `uncovered` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "SERVICE_AREA_NOT_COVERED": {
                    "value": {
                      "message": "Bu hizmet bu bölgede verilmiyor; kapsam dışı hizmetler `uncovered` alanında.",
                      "code": "SERVICE_AREA_NOT_COVERED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "APPOINTMENT_REQUIRED",
          "SLOT_CONFLICT",
          "INVALID_SERVICE_ANSWER",
          "INVALID_SERVICE_ITEM",
          "LOCATION_REQUIRED",
          "SERVICE_AREA_NOT_COVERED",
          "ADDRESS_REQUIRED",
          "LEGAL_VERSION_CHANGED"
        ],
        "x-ai-hint": "Önce `POST /pricing/preview` ile tutarı gösterin, sonra bu uç, sonra `POST /payments`."
      }
    },
    "/bookings/{id}": {
      "get": {
        "operationId": "getBooking",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Rezervasyonu getir",
        "description": "Tek rezervasyon: durum, randevu, adres, kalemler (soru cevaplarıyla), atanan usta (kabul ettikten sonra), grup kardeşleri ve ziyaret başlangıç kodu. Aşama (`getRequestStage`): `pending`/`assigned` usta aranıyor, `accepted` usta atandı, `metadata.on_the_way_at` doluysa yolda, `in_progress`, `completed` (onay bekliyor), `confirmed`.\n\n**Erişim:** müşteri anahtarı · izin `read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "reference": {
                          "description": "Müşteriye ve ekibe gösterilen talep numarası (`UG-102609123456`).",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "status": {
                          "type": "string"
                        },
                        "amount": {
                          "description": "Sunucunun hesapladığı tutar, tam TL.",
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "group_id": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "request"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "customer_id": "cus_01J00000000000000000000000",
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "base_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "unit_price": 750,
                        "variant_id": "variant_01J00000000000000000000000"
                      }
                    ],
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "title": "Klima Bakımı — Standart",
                    "notes": null,
                    "status": "pending",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "amount": 750,
                    "currency_code": "try",
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "address_summary": "Test Sok. 1 D:2",
                    "assigned_usta_id": null,
                    "cart_id": null,
                    "order_id": null,
                    "cancelled_at": null,
                    "cancel_reason": null,
                    "cancelled_by": null,
                    "metadata": {
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "offered_at": "2026-10-01T09:00:00.000Z",
                      "dispatch_note": "no_matching_usta",
                      "ug_pricing_type": "fixed",
                      "offered_usta_ids": [],
                      "ug_fixed_price_checkout": true
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null,
                    "assigned_usta": null,
                    "customer": {
                      "id": "cus_01J00000000000000000000000",
                      "display_name": "odeme T."
                    },
                    "group_siblings": null,
                    "order": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "read"
      }
    },
    "/bookings/{id}/cancel": {
      "post": {
        "operationId": "cancelBooking",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Rezervasyonu iptal et",
        "description": "Aşamaya göre karar verir: ödeme yoksa iptal, usta işe başlamadan önce tam iade talebi, usta yoldaysa yol ücreti kesilerek iade talebi; iş başladıysa 409 `CANCEL_NOT_ALLOWED` (anlaşmazlık açın). İptalde para hareket etmez: iade talebini ekip sonuçlandırır.\n\n**Erişim:** müşteri anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "scope": {
                    "description": "`group`: gruplu rezervasyonun bütün bacakları.",
                    "type": "string",
                    "enum": [
                      "single",
                      "group"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "legs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": {}
                      }
                    },
                    "refund_requests": {
                      "description": "Tutulan her ödeme için açılan iade talebi; para iptalde hareket etmez, ekip iadeyi yapar.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "request",
                    "legs",
                    "refund_requests"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "customer_id": "cus_01J00000000000000000000000",
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "base_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "unit_price": 750,
                        "variant_id": "variant_01J00000000000000000000000"
                      }
                    ],
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "title": "Klima Bakımı — Standart",
                    "notes": null,
                    "status": "cancelled",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "amount": 750,
                    "currency_code": "try",
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "address_summary": "Test Sok. 1 D:2",
                    "assigned_usta_id": null,
                    "cart_id": null,
                    "order_id": null,
                    "cancelled_at": "2026-10-01T09:00:00.000Z",
                    "cancel_reason": "Planım değişti",
                    "cancelled_by": "cus_01J00000000000000000000000",
                    "metadata": {
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "offered_at": "2026-10-01T09:00:00.000Z",
                      "dispatch_note": "no_matching_usta",
                      "ug_pricing_type": "fixed",
                      "offered_usta_ids": [],
                      "ug_fixed_price_checkout": true,
                      "cancelled_at": "2026-10-01T09:00:00.000Z",
                      "cancelled_by_role": "customer"
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  },
                  "legs": [
                    {
                      "request": {
                        "id": "01J00000000000000000000000",
                        "reference": "UG-102610123456",
                        "customer_id": "cus_01J00000000000000000000000",
                        "product_id": "prod_01J00000000000000000000000",
                        "variant_id": "variant_01J00000000000000000000000",
                        "items": [
                          {
                            "title": "Klima Bakımı — Standart",
                            "quantity": 1,
                            "base_price": 750,
                            "product_id": "prod_01J00000000000000000000000",
                            "unit_price": 750,
                            "variant_id": "variant_01J00000000000000000000000"
                          }
                        ],
                        "category_handle": "klima",
                        "group_id": null,
                        "group_order": null,
                        "title": "Klima Bakımı — Standart",
                        "notes": null,
                        "status": "cancelled",
                        "pricing_type": "fixed",
                        "fixed_price_checkout": true,
                        "amount": 750,
                        "currency_code": "try",
                        "appointment_date": "2026-10-06",
                        "appointment_slot": "09:00-11:00",
                        "address_summary": "Test Sok. 1 D:2",
                        "assigned_usta_id": null,
                        "cart_id": null,
                        "order_id": null,
                        "cancelled_at": "2026-10-01T09:00:00.000Z",
                        "cancel_reason": "Planım değişti",
                        "cancelled_by": "cus_01J00000000000000000000000",
                        "metadata": {
                          "city": "İstanbul",
                          "district": "Kadıköy",
                          "offered_at": "2026-10-01T09:00:00.000Z",
                          "dispatch_note": "no_matching_usta",
                          "ug_pricing_type": "fixed",
                          "offered_usta_ids": [],
                          "ug_fixed_price_checkout": true,
                          "cancelled_at": "2026-10-01T09:00:00.000Z",
                          "cancelled_by_role": "customer"
                        },
                        "created_at": "2026-10-01T09:00:00.000Z",
                        "updated_at": "2026-10-01T09:00:00.000Z",
                        "deleted_at": null
                      },
                      "outcome": {
                        "allowed": true,
                        "refund": "full",
                        "fee": 0,
                        "refund_amount": 750
                      },
                      "refund_requests": [
                        {
                          "escrow_id": "01J00000000000000000000000",
                          "ticket_id": "01J00000000000000000000000",
                          "amount": 750
                        }
                      ]
                    }
                  ],
                  "refund_requests": [
                    {
                      "escrow_id": "01J00000000000000000000000",
                      "ticket_id": "01J00000000000000000000000",
                      "amount": 750
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `REQUEST_NOT_FOUND` — Talep bulunamadı.\n- `GROUP_NOT_ALLOWED` — Grup bulunamadı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "REQUEST_NOT_FOUND": {
                    "value": {
                      "message": "Talep bulunamadı.",
                      "code": "REQUEST_NOT_FOUND"
                    }
                  },
                  "GROUP_NOT_ALLOWED": {
                    "value": {
                      "message": "Grup bulunamadı.",
                      "code": "GROUP_NOT_ALLOWED"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `CANCEL_NOT_ALLOWED` — İş bu aşamada iptal edilemez; anlaşmazlık açın.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "CANCEL_NOT_ALLOWED": {
                    "value": {
                      "message": "İş bu aşamada iptal edilemez; anlaşmazlık açın.",
                      "code": "CANCEL_NOT_ALLOWED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "CANCEL_NOT_ALLOWED",
          "REQUEST_NOT_FOUND",
          "GROUP_NOT_ALLOWED"
        ]
      }
    },
    "/bookings/{id}/confirm": {
      "post": {
        "operationId": "confirmBooking",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "İşi onayla",
        "description": "Tamamlanan işi onaylar ve tutulan bütün ödemeleri ustaya serbest bırakır. Geri alınamaz. İade talebi ya da anlaşmazlık açıksa 409.\n\n**Erişim:** müşteri anahtarı · izin `money`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    },
                    "escrows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "status"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "total_payout": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "request",
                    "escrows",
                    "total_payout"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "customer_id": "cus_01J00000000000000000000000",
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "base_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "unit_price": 750,
                        "variant_id": "variant_01J00000000000000000000000"
                      }
                    ],
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "title": "Klima Bakımı — Standart",
                    "notes": null,
                    "status": "completed",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "amount": 750,
                    "currency_code": "try",
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "address_summary": "Test Sok. 1 D:2",
                    "assigned_usta_id": "cus_01J00000000000000000000000",
                    "cart_id": null,
                    "order_id": null,
                    "cancelled_at": null,
                    "cancel_reason": null,
                    "cancelled_by": null,
                    "metadata": {
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "offered_at": "2026-10-01T09:00:00.000Z",
                      "start_code": "482913",
                      "started_at": "2026-10-01T09:00:00.000Z",
                      "completed_at": "2026-10-01T09:00:00.000Z",
                      "dispatch_note": null,
                      "on_the_way_at": "2026-10-01T09:00:00.000Z",
                      "start_code_at": "2026-10-01T09:00:00.000Z",
                      "completion_code": "482913",
                      "completion_note": "Klima bakımı yapıldı, filtreler temizlendi, gaz basıncı ölçüldü ve dolum tamamlandı.",
                      "ug_pricing_type": "fixed",
                      "offered_usta_ids": [
                        "cus_01J00000000000000000000000"
                      ],
                      "completion_photos": [
                        {
                          "url": "https://api.example.com/static/shared/private-1790000000000-ug-cus_01J00000000000000000000000-1790000000000.png"
                        }
                      ],
                      "completion_code_at": "2026-10-01T09:00:00.000Z",
                      "ug_fixed_price_checkout": true,
                      "confirmed_at": "2026-10-01T09:00:00.000Z"
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  },
                  "escrow": {
                    "id": "01J00000000000000000000000",
                    "order_id": null,
                    "service_request_id": "01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "usta_id": "cus_01J00000000000000000000000",
                    "kind": "primary",
                    "extra_work_id": null,
                    "amount": 750,
                    "currency_code": "try",
                    "commission_rate": 0.15,
                    "commission_amount": 112,
                    "payout_amount": 638,
                    "refunded_amount": 0,
                    "status": "released_to_technician",
                    "provider": "card-mock",
                    "payment_session_id": null,
                    "transaction_id": "MOCK-01J00000000000000000000000",
                    "released_at": "2026-10-01T09:00:00.000Z",
                    "held_at": "2026-10-01T09:00:00.000Z",
                    "disputed_at": null,
                    "dispute_reason": null,
                    "refund_requested_at": null,
                    "refunded_at": null,
                    "refund_reason": null,
                    "refund_reference": null,
                    "refund_channel": null,
                    "refund_ticket_id": null,
                    "metadata": {
                      "released_at": "2026-10-01T09:00:00.000Z",
                      "payout_provider": "stub",
                      "payout_reference": "PAYOUT-STUB-1790000000000-000000",
                      "commission_source": "services"
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  },
                  "escrows": [
                    {
                      "id": "01J00000000000000000000000",
                      "order_id": null,
                      "service_request_id": "01J00000000000000000000000",
                      "customer_id": "cus_01J00000000000000000000000",
                      "usta_id": "cus_01J00000000000000000000000",
                      "kind": "primary",
                      "extra_work_id": null,
                      "amount": 750,
                      "currency_code": "try",
                      "commission_rate": 0.15,
                      "commission_amount": 112,
                      "payout_amount": 638,
                      "refunded_amount": 0,
                      "status": "released_to_technician",
                      "provider": "card-mock",
                      "payment_session_id": null,
                      "transaction_id": "MOCK-01J00000000000000000000000",
                      "released_at": "2026-10-01T09:00:00.000Z",
                      "held_at": "2026-10-01T09:00:00.000Z",
                      "disputed_at": null,
                      "dispute_reason": null,
                      "refund_requested_at": null,
                      "refunded_at": null,
                      "refund_reason": null,
                      "refund_reference": null,
                      "refund_channel": null,
                      "refund_ticket_id": null,
                      "metadata": {
                        "released_at": "2026-10-01T09:00:00.000Z",
                        "payout_provider": "stub",
                        "payout_reference": "PAYOUT-STUB-1790000000000-000000",
                        "commission_source": "services"
                      },
                      "created_at": "2026-10-01T09:00:00.000Z",
                      "updated_at": "2026-10-01T09:00:00.000Z",
                      "deleted_at": null
                    },
                    {
                      "id": "01J00000000000000000000000",
                      "order_id": null,
                      "service_request_id": "01J00000000000000000000000",
                      "customer_id": "cus_01J00000000000000000000000",
                      "usta_id": "cus_01J00000000000000000000000",
                      "kind": "extra_work",
                      "extra_work_id": "01J00000000000000000000000",
                      "amount": 400,
                      "currency_code": "try",
                      "commission_rate": 0.15,
                      "commission_amount": 60,
                      "payout_amount": 340,
                      "refunded_amount": 0,
                      "status": "released_to_technician",
                      "provider": "card-mock",
                      "payment_session_id": null,
                      "transaction_id": "MOCK-EXTRA-01J00000000000000000000000",
                      "released_at": "2026-10-01T09:00:00.000Z",
                      "held_at": "2026-10-01T09:00:00.000Z",
                      "disputed_at": null,
                      "dispute_reason": null,
                      "refund_requested_at": null,
                      "refunded_at": null,
                      "refund_reason": null,
                      "refund_reference": null,
                      "refund_channel": null,
                      "refund_ticket_id": null,
                      "metadata": {
                        "released_at": "2026-10-01T09:00:00.000Z",
                        "payout_provider": "stub",
                        "payout_reference": "PAYOUT-STUB-1790000000000-000000",
                        "commission_source": "services"
                      },
                      "created_at": "2026-10-01T09:00:00.000Z",
                      "updated_at": "2026-10-01T09:00:00.000Z",
                      "deleted_at": null
                    }
                  ],
                  "total_payout": 978
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `REFUND_REQUEST_PENDING` — Bekleyen bir iade talebi var; önce o sonuçlanmalı.\n- `ESCROW_DISPUTED` — Ödeme için açık bir anlaşmazlık var.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "REFUND_REQUEST_PENDING": {
                    "value": {
                      "message": "Bekleyen bir iade talebi var; önce o sonuçlanmalı.",
                      "code": "REFUND_REQUEST_PENDING"
                    }
                  },
                  "ESCROW_DISPUTED": {
                    "value": {
                      "message": "Ödeme için açık bir anlaşmazlık var.",
                      "code": "ESCROW_DISPUTED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "money",
        "x-ug-error-codes": [
          "REFUND_REQUEST_PENDING",
          "ESCROW_DISPUTED"
        ],
        "x-ai-hint": "Yalnızca müşteri işin bittiğini açıkça onayladıktan sonra çağırın."
      }
    },
    "/bookings/{id}/contracts": {
      "get": {
        "operationId": "getBookingContracts",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Onaylanan sözleşmeyi getir",
        "description": "Rezervasyonda onaylanan sözleşmelerin sunucunun doldurduğu kopyası.\n\n**Erişim:** müşteri anahtarı · izin `read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "acceptance": {}
                  },
                  "required": [
                    "acceptance"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "read"
      }
    },
    "/bookings/{id}/photos": {
      "post": {
        "operationId": "addBookingPhotos",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Fotoğraf ekle",
        "description": "Usta atanmadan önce işe fotoğraf ekler (listeyi değiştirir). Atamadan sonra 409 `PHOTOS_LOCKED`.\n\n**Erişim:** müşteri anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "photos": {
                    "description": "`POST /uploads/photo` ile yüklenmiş dosya adresleri (en çok 5). Bu sunucunun üretmediği adresler sessizce düşürülür.",
                    "anyOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      {
                        "type": "string"
                      }
                    ]
                  }
                },
                "required": [
                  "photos"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    },
                    "photos": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "request",
                    "photos"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `PHOTOS_LOCKED` — Usta atandıktan sonra fotoğraf eklenemez.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PHOTOS_LOCKED": {
                    "value": {
                      "message": "Usta atandıktan sonra fotoğraf eklenemez.",
                      "code": "PHOTOS_LOCKED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "PHOTOS_LOCKED"
        ]
      }
    },
    "/bookings/{id}/reschedule": {
      "post": {
        "operationId": "answerReschedule",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Saat önerisine cevap ver",
        "description": "Ustanın önerdiği yeni saati kabul eder ya da reddeder.\n\n**Erişim:** müşteri anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "accept": {
                    "description": "`true` ustanın önerdiği yeni saati kabul eder, `false` reddeder.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "accept"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    },
                    "accepted": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "request",
                    "accepted"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `NO_PENDING_RESCHEDULE` — Onay bekleyen bir saat önerisi yok.\n- `SLOT_CONFLICT` — Bu gün ve saatte çakışan bir randevu var.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NO_PENDING_RESCHEDULE": {
                    "value": {
                      "message": "Onay bekleyen bir saat önerisi yok.",
                      "code": "NO_PENDING_RESCHEDULE"
                    }
                  },
                  "SLOT_CONFLICT": {
                    "value": {
                      "message": "Bu gün ve saatte çakışan bir randevu var.",
                      "code": "SLOT_CONFLICT"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "NO_PENDING_RESCHEDULE",
          "SLOT_CONFLICT"
        ]
      }
    },
    "/campaigns": {
      "get": {
        "operationId": "listCampaigns",
        "tags": [
          "Katalog"
        ],
        "summary": "Kampanyaları listele",
        "description": "Yayındaki kampanyalar (uygulamanın ana sayfasındaki bannerlar) ve kalan kotaları.\n\n**Erişim:** her iki rol · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaigns": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "campaigns"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/catalog": {
      "get": {
        "operationId": "getCatalog",
        "tags": [
          "Katalog"
        ],
        "summary": "Kataloğu getir",
        "description": "Yayındaki bütün kategoriler ve hizmetler: paketler (varyantlar), başlangıç fiyatı, bölge fiyatları ve hizmet soruları. Rezervasyon için `variant_id`/`product_id` buradan alınır. `ETag` taşır; `If-None-Match` ile 304 döner.\n\n**Erişim:** her iki rol · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "categories": {
                      "description": "Kategoriler, panelin sırasıyla. `ug_status`: `active` ya da `coming_soon` (yakında, rezervasyon yok); pasifler listelenmez.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "handle": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "handle"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "products": {
                      "description": "Yayındaki hizmetler; varyantlar, `ug_min_price`, `ug_zone_prices`, `ug_service_questions` ile.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "handle": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "title",
                          "handle"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "categories",
                    "products"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "categories": [
                    {
                      "id": "pcat_01J00000000000000000000000",
                      "name": "Klima",
                      "handle": "klima",
                      "description": "",
                      "is_active": true,
                      "rank": 0,
                      "metadata": {},
                      "icon": "ac-unit",
                      "color": "#0066FF",
                      "backgroundColor": "#e0f2fe",
                      "image": "https://images.unsplash.com/photo-1790000000000-08b45d6a269e?q=80&w=400&auto=format&fit=crop",
                      "card_mode": null,
                      "text_color": null,
                      "ug_min_price": null,
                      "ug_max_price": null,
                      "ug_status": "active",
                      "ug_coming_soon": false,
                      "ug_product_count": 1
                    }
                  ],
                  "products": [
                    {
                      "id": "prod_01J00000000000000000000000",
                      "title": "Klima Bakımı",
                      "handle": "klima-bakimi",
                      "description": null,
                      "status": "published",
                      "metadata": {
                        "ug_pricing_type": "fixed",
                        "ug_service_areas": [
                          "istanbul"
                        ],
                        "ug_fixed_price_checkout": true
                      },
                      "thumbnail": null,
                      "categories": [
                        {
                          "id": "pcat_01J00000000000000000000000",
                          "handle": "klima",
                          "name": "Klima",
                          "metadata": {}
                        }
                      ],
                      "variants": [
                        {
                          "id": "variant_01J00000000000000000000000",
                          "title": "Standart",
                          "sku": null
                        }
                      ],
                      "ug_pricing_type": "fixed",
                      "ug_fixed_price_checkout": true,
                      "ug_min_price": null,
                      "ug_max_price": null,
                      "ug_zone_prices": {},
                      "ug_service_questions": [],
                      "ug_addons": []
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read",
        "x-ai-hint": "Rezervasyondan önce bir kez çağırın ve önbelleğe alın; hizmet kimlikleri buradan gelir."
      }
    },
    "/catalog/search": {
      "get": {
        "operationId": "searchCatalog",
        "tags": [
          "Katalog"
        ],
        "summary": "Katalogda ara",
        "description": "Hizmet, kategori ve içerik sayfalarında tam metin arama. En az 2 karakter; arama altyapısı kapalıysa boş liste döner.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Arama metni, en az 2 karakter.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "En çok sonuç, 1–50 (varsayılan 20).",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "products": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "categories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "pages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "products",
                    "categories",
                    "pages"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/chat": {
      "get": {
        "operationId": "listChatThreads",
        "tags": [
          "Sohbet"
        ],
        "summary": "Sohbetleri listele",
        "description": "Hesabın sohbetleri, okunmamış sayısıyla; destek sohbeti önce.\n\n**Erişim:** her iki rol · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "threads": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "service_request_id": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "service_request_id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "threads"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/chat/{serviceRequestId}": {
      "get": {
        "operationId": "getChat",
        "tags": [
          "Sohbet"
        ],
        "summary": "Sohbeti getir",
        "description": "Bir işin sohbeti (usta atandıktan sonra açılır). `after` ile yalnızca yeni mesajlar; okundu bilgisi yazılır.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "serviceRequestId",
            "in": "path",
            "required": true,
            "description": "Rezervasyonun (talebin) kimliği.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Son görülen mesajın kimliği; yalnızca ondan sonrakiler döner (yoklama).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "thread": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    },
                    "messages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "incremental": {
                      "type": "boolean"
                    },
                    "viewer_role": {
                      "type": "string",
                      "enum": [
                        "customer",
                        "usta"
                      ]
                    }
                  },
                  "required": [
                    "thread",
                    "messages",
                    "incremental",
                    "viewer_role"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `NO_USTA_ASSIGNED` — Bu işe atanmış bir usta yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NO_USTA_ASSIGNED": {
                    "value": {
                      "message": "Bu işe atanmış bir usta yok.",
                      "code": "NO_USTA_ASSIGNED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read",
        "x-ug-error-codes": [
          "NO_USTA_ASSIGNED"
        ]
      }
    },
    "/chat/{serviceRequestId}/messages": {
      "post": {
        "operationId": "sendChatMessage",
        "tags": [
          "Sohbet"
        ],
        "summary": "Mesaj gönder",
        "description": "Metin (en çok 2000 karakter) ya da `POST /uploads/photo` görseli gönderir.\n\n**Erişim:** her iki rol · izin `write`",
        "parameters": [
          {
            "name": "serviceRequestId",
            "in": "path",
            "required": true,
            "description": "Rezervasyonun (talebin) kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "image_url": {
                    "description": "`POST /uploads/photo` adresi.",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    },
                    "viewer_role": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "message",
                    "viewer_role"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `NO_USTA_ASSIGNED` — Bu işe atanmış bir usta yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NO_USTA_ASSIGNED": {
                    "value": {
                      "message": "Bu işe atanmış bir usta yok.",
                      "code": "NO_USTA_ASSIGNED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "NO_USTA_ASSIGNED"
        ]
      }
    },
    "/extra-work": {
      "get": {
        "operationId": "listExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Ek işleri listele",
        "description": "Hesabın ek iş talepleri; `service_request_id` ile tek bir işin.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "service_request_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_works": {
                      "type": "array",
                      "items": {
                        "description": "Ek iş (ek ücret) talebi.",
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                            "type": "string"
                          },
                          "service_request_id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "status",
                          "service_request_id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "extra_works"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "createExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Ek ücret talep et",
        "description": "İş başında çıkan ek işi kalem kalem müşterinin onayına sunar (1–10 kalem). Yalnızca başlamış ya da tamamlanmış, onaylanmamış işte; açıkta bir talep varken ikincisi açılmaz.\n\n**Erişim:** usta anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "service_request_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "line_items": {
                    "minItems": 1,
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "description": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 500
                        },
                        "amount": {
                          "description": "Kalem tutarı, pozitif. Tam TL (750 = ₺750).",
                          "type": "number"
                        }
                      },
                      "required": [
                        "description",
                        "amount"
                      ]
                    }
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "photos": {
                    "maxItems": 5,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "description": "Yüklenen dosyanın adresi.",
                          "type": "string",
                          "minLength": 1
                        },
                        "file_name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mime_type": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "url"
                      ]
                    }
                  }
                },
                "required": [
                  "service_request_id",
                  "line_items"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_work": {
                      "description": "Ek iş (ek ücret) talebi.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                          "type": "string"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "extra_work"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "extra_work": {
                    "id": "01J00000000000000000000000",
                    "service_request_id": "01J00000000000000000000000",
                    "usta_id": "cus_01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "line_items": [
                      {
                        "description": "Gaz dolumu",
                        "amount": 400
                      }
                    ],
                    "total": 400,
                    "currency_code": "try",
                    "note": null,
                    "photos": null,
                    "status": "pending_customer",
                    "revision": 0,
                    "history": [
                      {
                        "at": "2026-10-01T09:00:00.000Z",
                        "actor": "usta",
                        "actor_id": "cus_01J00000000000000000000000",
                        "action": "created",
                        "revision": 0,
                        "line_items": [
                          {
                            "description": "Gaz dolumu",
                            "amount": 400
                          }
                        ],
                        "total": 400,
                        "note": null
                      }
                    ],
                    "rejection_reason_code": null,
                    "rejection_reason_text": null,
                    "escrow_id": null,
                    "dispute_id": null,
                    "approved_at": null,
                    "rejected_at": null,
                    "withdrawn_at": null,
                    "disputed_at": null,
                    "resolved_at": null,
                    "metadata": null,
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `INVALID_LINE_ITEMS` — Kalemler geçersiz: 1–10 kalem, her biri açıklama ve pozitif tutar.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "INVALID_LINE_ITEMS": {
                    "value": {
                      "message": "Kalemler geçersiz: 1–10 kalem, her biri açıklama ve pozitif tutar.",
                      "code": "INVALID_LINE_ITEMS"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `NOT_YOUR_JOB` — Bu iş size atanmamış.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "NOT_YOUR_JOB": {
                    "value": {
                      "message": "Bu iş size atanmamış.",
                      "code": "NOT_YOUR_JOB"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `INVALID_JOB_STATUS` — İşin durumu buna izin vermiyor (yalnızca başlamış ya da tamamlanmış iş).\n- `JOB_ALREADY_CONFIRMED` — Müşteri işi onayladı.\n- `EXTRA_WORK_PENDING` — Cevap bekleyen bir ek iş talebi var; mevcut kayıt `extra_work` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INVALID_JOB_STATUS": {
                    "value": {
                      "message": "İşin durumu buna izin vermiyor (yalnızca başlamış ya da tamamlanmış iş).",
                      "code": "INVALID_JOB_STATUS"
                    }
                  },
                  "JOB_ALREADY_CONFIRMED": {
                    "value": {
                      "message": "Müşteri işi onayladı.",
                      "code": "JOB_ALREADY_CONFIRMED"
                    }
                  },
                  "EXTRA_WORK_PENDING": {
                    "value": {
                      "message": "Cevap bekleyen bir ek iş talebi var; mevcut kayıt `extra_work` alanında.",
                      "code": "EXTRA_WORK_PENDING"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "INVALID_LINE_ITEMS",
          "NOT_YOUR_JOB",
          "INVALID_JOB_STATUS",
          "JOB_ALREADY_CONFIRMED",
          "EXTRA_WORK_PENDING"
        ]
      }
    },
    "/extra-work/{id}": {
      "get": {
        "operationId": "getExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Ek işi getir",
        "description": "Tek ek iş talebi ve hangi tarafta olduğunuz (`side`).\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_work": {
                      "description": "Ek iş (ek ücret) talebi.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                          "type": "string"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    },
                    "side": {
                      "type": "string",
                      "enum": [
                        "usta",
                        "customer"
                      ]
                    }
                  },
                  "required": [
                    "extra_work",
                    "side"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/extra-work/{id}/approve": {
      "post": {
        "operationId": "approveExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Ek işi onayla",
        "description": "Ek ücreti kabul eder ve onun için ayrı bir ödeme açar (`payment`, `POST /payments` ile aynı biçim).\n\n**Erişim:** müşteri anahtarı · izin `money`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "payment_method": {
                    "description": "`card` (varsayılan) ya da `bank_transfer`.",
                    "type": "string",
                    "enum": [
                      "card",
                      "bank_transfer"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_work": {
                      "description": "Ek iş (ek ücret) talebi.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                          "type": "string"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    },
                    "escrow": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status"
                      ],
                      "additionalProperties": {}
                    },
                    "payment": {
                      "description": "Ödemenin nasıl tamamlanacağı.",
                      "type": "object",
                      "properties": {
                        "mode": {
                          "description": "`gateway`: müşteriyi `payment_url`'e yönlendirin, 3D Secure bankada tamamlanır ve ödeme bankanın onayıyla tutulur. `bank_transfer`: `reference` açıklamaya yazılarak `amount` tutarında havale. `mock`: yalnızca test ortamı, ödeme hemen tutuldu.",
                          "type": "string",
                          "enum": [
                            "gateway",
                            "mock",
                            "bank_transfer"
                          ]
                        },
                        "payment_url": {
                          "description": "Yalnızca `gateway`: bankanın ödeme sayfasına açılan adres (tarayıcı ya da WebView).",
                          "type": "string"
                        },
                        "order_number": {
                          "type": "string"
                        },
                        "reference": {
                          "description": "Havale açıklamasına yazılacak talep numarası.",
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        },
                        "accounts": {
                          "description": "Havale yapılabilecek hesaplar.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "iban": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "iban"
                            ],
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "mode"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "extra_work",
                    "escrow",
                    "payment"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "extra_work": {
                    "id": "01J00000000000000000000000",
                    "service_request_id": "01J00000000000000000000000",
                    "usta_id": "cus_01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "line_items": [
                      {
                        "amount": 400,
                        "description": "Gaz dolumu"
                      }
                    ],
                    "total": 400,
                    "currency_code": "try",
                    "note": null,
                    "photos": null,
                    "status": "approved",
                    "revision": 0,
                    "history": [
                      {
                        "at": "2026-10-01T09:00:00.000Z",
                        "note": null,
                        "actor": "usta",
                        "total": 400,
                        "action": "created",
                        "actor_id": "cus_01J00000000000000000000000",
                        "revision": 0,
                        "line_items": [
                          {
                            "amount": 400,
                            "description": "Gaz dolumu"
                          }
                        ]
                      },
                      {
                        "at": "2026-10-01T09:00:00.000Z",
                        "actor": "customer",
                        "actor_id": "cus_01J00000000000000000000000",
                        "action": "approved",
                        "revision": 0,
                        "total": 400
                      }
                    ],
                    "rejection_reason_code": null,
                    "rejection_reason_text": null,
                    "escrow_id": "01J00000000000000000000000",
                    "dispute_id": null,
                    "approved_at": "2026-10-01T09:00:00.000Z",
                    "rejected_at": null,
                    "withdrawn_at": null,
                    "disputed_at": null,
                    "resolved_at": null,
                    "metadata": null,
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  },
                  "escrow": {
                    "id": "01J00000000000000000000000",
                    "order_id": null,
                    "service_request_id": "01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "usta_id": "cus_01J00000000000000000000000",
                    "kind": "extra_work",
                    "extra_work_id": "01J00000000000000000000000",
                    "amount": 400,
                    "currency_code": "try",
                    "commission_rate": 0.15,
                    "commission_amount": 60,
                    "payout_amount": 340,
                    "refunded_amount": 0,
                    "status": "held",
                    "provider": "card-mock",
                    "payment_session_id": null,
                    "transaction_id": "MOCK-EXTRA-01J00000000000000000000000",
                    "released_at": null,
                    "held_at": "2026-10-01T09:00:00.000Z",
                    "disputed_at": null,
                    "dispute_reason": null,
                    "refund_requested_at": null,
                    "refunded_at": null,
                    "refund_reason": null,
                    "refund_reference": null,
                    "refund_channel": null,
                    "refund_ticket_id": null,
                    "metadata": {
                      "commission_source": "services"
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  },
                  "payment": {
                    "mode": "mock"
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `PAYMENT_FAILED` — Ödeme başlatılamadı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "PAYMENT_FAILED": {
                    "value": {
                      "message": "Ödeme başlatılamadı.",
                      "code": "PAYMENT_FAILED"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `NOT_YOUR_REQUEST` — Bu talep size ait değil.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_YOUR_REQUEST": {
                    "value": {
                      "message": "Bu talep size ait değil.",
                      "code": "NOT_YOUR_REQUEST"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `NO_USTA_ASSIGNED` — Bu işe atanmış bir usta yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NO_USTA_ASSIGNED": {
                    "value": {
                      "message": "Bu işe atanmış bir usta yok.",
                      "code": "NO_USTA_ASSIGNED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Hizmet yapılandırılmamış.\n\n- `PAYMENT_GATEWAY_UNCONFIGURED` — Kartla ödeme şu anda kullanılamıyor.\n- `BANK_TRANSFER_UNCONFIGURED` — Havale şu anda kullanılamıyor.\n- `HOSTED_PAYMENT_UNAVAILABLE` — Kartla ödeme bu kanaldan henüz açık değil; havale kullanın.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PAYMENT_GATEWAY_UNCONFIGURED": {
                    "value": {
                      "message": "Kartla ödeme şu anda kullanılamıyor.",
                      "code": "PAYMENT_GATEWAY_UNCONFIGURED"
                    }
                  },
                  "BANK_TRANSFER_UNCONFIGURED": {
                    "value": {
                      "message": "Havale şu anda kullanılamıyor.",
                      "code": "BANK_TRANSFER_UNCONFIGURED"
                    }
                  },
                  "HOSTED_PAYMENT_UNAVAILABLE": {
                    "value": {
                      "message": "Kartla ödeme bu kanaldan henüz açık değil; havale kullanın.",
                      "code": "HOSTED_PAYMENT_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "money",
        "x-ug-error-codes": [
          "NOT_YOUR_REQUEST",
          "NO_USTA_ASSIGNED",
          "PAYMENT_GATEWAY_UNCONFIGURED",
          "BANK_TRANSFER_UNCONFIGURED",
          "PAYMENT_FAILED",
          "HOSTED_PAYMENT_UNAVAILABLE"
        ]
      }
    },
    "/extra-work/{id}/counter-offer": {
      "post": {
        "operationId": "counterExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Yeni ek iş teklifi ver",
        "description": "Reddedilen ek ücrete daha düşük bir teklif verir; en çok 2 revizyon.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "line_items": {
                    "minItems": 1,
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "description": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 500
                        },
                        "amount": {
                          "description": "Kalem tutarı, pozitif. Tam TL (750 = ₺750).",
                          "type": "number"
                        }
                      },
                      "required": [
                        "description",
                        "amount"
                      ]
                    }
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 2000
                  }
                },
                "required": [
                  "line_items"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_work": {
                      "description": "Ek iş (ek ücret) talebi.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                          "type": "string"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "extra_work"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `INVALID_LINE_ITEMS` — Kalemler geçersiz: 1–10 kalem, her biri açıklama ve pozitif tutar.\n- `AMOUNT_NOT_LOWER` — Yeni teklif öncekinden düşük olmalı (en çok 2 revizyon).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "INVALID_LINE_ITEMS": {
                    "value": {
                      "message": "Kalemler geçersiz: 1–10 kalem, her biri açıklama ve pozitif tutar.",
                      "code": "INVALID_LINE_ITEMS"
                    }
                  },
                  "AMOUNT_NOT_LOWER": {
                    "value": {
                      "message": "Yeni teklif öncekinden düşük olmalı (en çok 2 revizyon).",
                      "code": "AMOUNT_NOT_LOWER"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `INVALID_STATUS` — Kaydın durumu buna izin vermiyor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INVALID_STATUS": {
                    "value": {
                      "message": "Kaydın durumu buna izin vermiyor.",
                      "code": "INVALID_STATUS"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "INVALID_LINE_ITEMS",
          "AMOUNT_NOT_LOWER",
          "INVALID_STATUS"
        ]
      }
    },
    "/extra-work/{id}/escalate": {
      "post": {
        "operationId": "escalateExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Ekibe itiraz et",
        "description": "Reddedilen ek ücret için ekipten karar ister. Ödeme dondurulmaz; ekip usta lehine karar verirse müşteri normal onay yoluyla öder.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "statement": {
                    "type": "string",
                    "minLength": 50,
                    "maxLength": 500
                  },
                  "photos": {
                    "maxItems": 5,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "description": "Yüklenen dosyanın adresi.",
                          "type": "string",
                          "minLength": 1
                        },
                        "file_name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mime_type": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "url"
                      ]
                    }
                  }
                },
                "required": [
                  "statement"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_work": {
                      "description": "Ek iş (ek ücret) talebi.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                          "type": "string"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    },
                    "ticket": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "extra_work",
                    "ticket"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `INVALID_STATEMENT` — İtiraz açıklaması 50–500 karakter olmalı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "INVALID_STATEMENT": {
                    "value": {
                      "message": "İtiraz açıklaması 50–500 karakter olmalı.",
                      "code": "INVALID_STATEMENT"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "INVALID_STATEMENT"
        ]
      }
    },
    "/extra-work/{id}/reject": {
      "post": {
        "operationId": "rejectExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Ek işi reddet",
        "description": "Ek ücreti gerekçesiyle reddeder; usta daha düşük bir teklif verebilir ya da itiraz edebilir.\n\n**Erişim:** müşteri anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "description": "Ret gerekçesinin kodu.",
                    "type": "string",
                    "enum": [
                      "price_too_high",
                      "not_needed",
                      "not_agreed",
                      "quality_concern",
                      "other"
                    ]
                  },
                  "text": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "code",
                  "text"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_work": {
                      "description": "Ek iş (ek ücret) talebi.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                          "type": "string"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "extra_work"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `INVALID_REASON_CODE` — Ret gerekçesi kodu geçersiz.\n- `REASON_TOO_SHORT` — Gerekçe en az 10 karakter olmalı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "INVALID_REASON_CODE": {
                    "value": {
                      "message": "Ret gerekçesi kodu geçersiz.",
                      "code": "INVALID_REASON_CODE"
                    }
                  },
                  "REASON_TOO_SHORT": {
                    "value": {
                      "message": "Gerekçe en az 10 karakter olmalı.",
                      "code": "REASON_TOO_SHORT"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `NOT_YOUR_REQUEST` — Bu talep size ait değil.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_YOUR_REQUEST": {
                    "value": {
                      "message": "Bu talep size ait değil.",
                      "code": "NOT_YOUR_REQUEST"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `INVALID_STATUS` — Kaydın durumu buna izin vermiyor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INVALID_STATUS": {
                    "value": {
                      "message": "Kaydın durumu buna izin vermiyor.",
                      "code": "INVALID_STATUS"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "NOT_YOUR_REQUEST",
          "INVALID_REASON_CODE",
          "REASON_TOO_SHORT",
          "INVALID_STATUS"
        ]
      }
    },
    "/extra-work/{id}/withdraw": {
      "post": {
        "operationId": "withdrawExtraWork",
        "tags": [
          "Ek iş"
        ],
        "summary": "Ek işi geri çek",
        "description": "Cevap bekleyen ek ücret talebini geri çeker.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "extra_work": {
                      "description": "Ek iş (ek ücret) talebi.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_customer` → `approved` | `rejected` | `withdrawn`; `rejected` → yeni teklif ya da `disputed`.",
                          "type": "string"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "extra_work"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `INVALID_STATUS` — Kaydın durumu buna izin vermiyor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INVALID_STATUS": {
                    "value": {
                      "message": "Kaydın durumu buna izin vermiyor.",
                      "code": "INVALID_STATUS"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "INVALID_STATUS"
        ]
      }
    },
    "/jobs": {
      "get": {
        "operationId": "listJobs",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "İşleri listele",
        "description": "Ustanın üstlendiği işler ve alabileceği açık işler (kategori, il, takvim ve onay kurallarına göre). Usta iş alamıyorsa liste boş gelir ve `usta_block` sebebini söyler (ör. `PENDING_ADMIN_APPROVAL`).\n\n**Erişim:** usta anahtarı · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requests": {
                      "description": "Ustanın kendi işleri ve alabileceği açık işler.",
                      "type": "array",
                      "items": {
                        "description": "Ustanın gördüğü iş. Kabul etmeden önce yalnızca il ve iş bilgisi; kabul sonrası tam adres ve müşterinin adı (soyadının baş harfi). Telefon hiçbir zaman verilmez: iletişim sohbetten.",
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "appointment_date": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "appointment_slot": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "status",
                          "appointment_date",
                          "appointment_slot"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "role": {
                      "type": "string"
                    },
                    "usta_block": {
                      "description": "Ustanın iş almasını engelleyen durum (ör. `PENDING_ADMIN_APPROVAL`), yoksa `null`.",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "usta_block_message": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "requests",
                    "role",
                    "usta_block",
                    "usta_block_message"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "requests": [
                    {
                      "id": "01J00000000000000000000000",
                      "reference": "UG-102610123456",
                      "title": "Klima Bakımı — Standart",
                      "status": "pending",
                      "category_handle": "klima",
                      "group_id": null,
                      "group_order": null,
                      "group_siblings": null,
                      "items": [
                        {
                          "title": "Klima Bakımı — Standart",
                          "quantity": 1,
                          "base_price": 750,
                          "product_id": "prod_01J00000000000000000000000",
                          "unit_price": 750,
                          "variant_id": "variant_01J00000000000000000000000"
                        }
                      ],
                      "product_id": "prod_01J00000000000000000000000",
                      "variant_id": "variant_01J00000000000000000000000",
                      "amount": 750,
                      "currency_code": "try",
                      "pricing_type": "fixed",
                      "fixed_price_checkout": true,
                      "appointment_date": "2026-10-06",
                      "appointment_slot": "09:00-11:00",
                      "notes": null,
                      "photos": [],
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "assigned_usta_id": null,
                      "created_at": "2026-10-01T09:00:00.000Z",
                      "updated_at": "2026-10-01T09:00:00.000Z",
                      "metadata": {
                        "city": "İstanbul",
                        "district": "Kadıköy",
                        "ug_pricing_type": "fixed",
                        "ug_fixed_price_checkout": true
                      }
                    }
                  ],
                  "role": "usta",
                  "usta_block": null,
                  "usta_block_message": null
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read",
        "x-ai-hint": "Yeni işleri görmek için 30–60 sn'de bir ya da `GET /notifications/sync` ile yoklayın."
      }
    },
    "/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "İşi getir",
        "description": "Tek iş. Kabul etmeden önce adres yalnızca il düzeyinde; müşteri adı kabulden sonra, telefon hiçbir zaman.\n\n**Erişim:** usta anahtarı · izin `read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "description": "Ustanın gördüğü iş. Kabul etmeden önce yalnızca il ve iş bilgisi; kabul sonrası tam adres ve müşterinin adı (soyadının baş harfi). Telefon hiçbir zaman verilmez: iletişim sohbetten.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "request"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `USTA_PROFILE_REQUIRED` — Önce usta profili oluşturulmalı.\n- `SERVICE_CATEGORIES_REQUIRED` — En az bir hizmet kategorisi seçilmeli.\n- `CATEGORY_NOT_COVERED` — İş, ustanın kategorileri arasında değil.\n- `CATEGORY_DOCUMENTS_REQUIRED` — Bu kategorinin işleri için onaylı belge gerekiyor.\n- `CITY_NOT_COVERED` — İş, ustanın ilinin dışında.\n- `OWN_REQUEST` — Usta kendi talebini alamaz.\n- `ALREADY_TAKEN` — İş başka bir ustada.\n- `PENDING_ADMIN_APPROVAL` — Hesap çağrı merkezi onayını bekliyor.\n- `NOT_AVAILABLE_AT_SLOT` — Usta o gün ve saatte çalışmıyor.\n- `AREA_NOT_COVERED` — Bu bölgede hizmet verilmiyor.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "USTA_PROFILE_REQUIRED": {
                    "value": {
                      "message": "Önce usta profili oluşturulmalı.",
                      "code": "USTA_PROFILE_REQUIRED"
                    }
                  },
                  "SERVICE_CATEGORIES_REQUIRED": {
                    "value": {
                      "message": "En az bir hizmet kategorisi seçilmeli.",
                      "code": "SERVICE_CATEGORIES_REQUIRED"
                    }
                  },
                  "CATEGORY_NOT_COVERED": {
                    "value": {
                      "message": "İş, ustanın kategorileri arasında değil.",
                      "code": "CATEGORY_NOT_COVERED"
                    }
                  },
                  "CATEGORY_DOCUMENTS_REQUIRED": {
                    "value": {
                      "message": "Bu kategorinin işleri için onaylı belge gerekiyor.",
                      "code": "CATEGORY_DOCUMENTS_REQUIRED"
                    }
                  },
                  "CITY_NOT_COVERED": {
                    "value": {
                      "message": "İş, ustanın ilinin dışında.",
                      "code": "CITY_NOT_COVERED"
                    }
                  },
                  "OWN_REQUEST": {
                    "value": {
                      "message": "Usta kendi talebini alamaz.",
                      "code": "OWN_REQUEST"
                    }
                  },
                  "ALREADY_TAKEN": {
                    "value": {
                      "message": "İş başka bir ustada.",
                      "code": "ALREADY_TAKEN"
                    }
                  },
                  "PENDING_ADMIN_APPROVAL": {
                    "value": {
                      "message": "Hesap çağrı merkezi onayını bekliyor.",
                      "code": "PENDING_ADMIN_APPROVAL"
                    }
                  },
                  "NOT_AVAILABLE_AT_SLOT": {
                    "value": {
                      "message": "Usta o gün ve saatte çalışmıyor.",
                      "code": "NOT_AVAILABLE_AT_SLOT"
                    }
                  },
                  "AREA_NOT_COVERED": {
                    "value": {
                      "message": "Bu bölgede hizmet verilmiyor.",
                      "code": "AREA_NOT_COVERED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "USTA_PROFILE_REQUIRED",
          "SERVICE_CATEGORIES_REQUIRED",
          "CATEGORY_NOT_COVERED",
          "CATEGORY_DOCUMENTS_REQUIRED",
          "CITY_NOT_COVERED",
          "OWN_REQUEST",
          "ALREADY_TAKEN",
          "PENDING_ADMIN_APPROVAL",
          "NOT_AVAILABLE_AT_SLOT",
          "AREA_NOT_COVERED"
        ]
      }
    },
    "/jobs/{id}/accept": {
      "post": {
        "operationId": "acceptJob",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "İşi kabul et",
        "description": "İşi üstlenir; ilk kabul eden alır, diğer tekliflerin hepsi geri çekilir. Ödemesi alınmamış iş kabul edilemez.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "description": "Ustanın gördüğü iş. Kabul etmeden önce yalnızca il ve iş bilgisi; kabul sonrası tam adres ve müşterinin adı (soyadının baş harfi). Telefon hiçbir zaman verilmez: iletişim sohbetten.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "request"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "title": "Klima Bakımı — Standart",
                    "status": "accepted",
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "group_siblings": null,
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "base_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "unit_price": 750,
                        "variant_id": "variant_01J00000000000000000000000"
                      }
                    ],
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "amount": 750,
                    "currency_code": "try",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "notes": null,
                    "photos": [],
                    "city": "İstanbul",
                    "district": "Kadıköy",
                    "assigned_usta_id": "cus_01J00000000000000000000000",
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "metadata": {
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "ug_pricing_type": "fixed",
                      "ug_fixed_price_checkout": true
                    },
                    "address_summary": "Test Sok. 1 D:2",
                    "order_id": null,
                    "customer": {
                      "id": "cus_01J00000000000000000000000",
                      "display_name": "is-akisi T."
                    },
                    "customer_id": "cus_01J00000000000000000000000"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `USTA_PROFILE_REQUIRED` — Önce usta profili oluşturulmalı.\n- `SERVICE_CATEGORIES_REQUIRED` — En az bir hizmet kategorisi seçilmeli.\n- `CATEGORY_NOT_COVERED` — İş, ustanın kategorileri arasında değil.\n- `CATEGORY_DOCUMENTS_REQUIRED` — Bu kategorinin işleri için onaylı belge gerekiyor.\n- `CITY_NOT_COVERED` — İş, ustanın ilinin dışında.\n- `OWN_REQUEST` — Usta kendi talebini alamaz.\n- `ALREADY_TAKEN` — İş başka bir ustada.\n- `PENDING_ADMIN_APPROVAL` — Hesap çağrı merkezi onayını bekliyor.\n- `NOT_AVAILABLE_AT_SLOT` — Usta o gün ve saatte çalışmıyor.\n- `AREA_NOT_COVERED` — Bu bölgede hizmet verilmiyor.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "USTA_PROFILE_REQUIRED": {
                    "value": {
                      "message": "Önce usta profili oluşturulmalı.",
                      "code": "USTA_PROFILE_REQUIRED"
                    }
                  },
                  "SERVICE_CATEGORIES_REQUIRED": {
                    "value": {
                      "message": "En az bir hizmet kategorisi seçilmeli.",
                      "code": "SERVICE_CATEGORIES_REQUIRED"
                    }
                  },
                  "CATEGORY_NOT_COVERED": {
                    "value": {
                      "message": "İş, ustanın kategorileri arasında değil.",
                      "code": "CATEGORY_NOT_COVERED"
                    }
                  },
                  "CATEGORY_DOCUMENTS_REQUIRED": {
                    "value": {
                      "message": "Bu kategorinin işleri için onaylı belge gerekiyor.",
                      "code": "CATEGORY_DOCUMENTS_REQUIRED"
                    }
                  },
                  "CITY_NOT_COVERED": {
                    "value": {
                      "message": "İş, ustanın ilinin dışında.",
                      "code": "CITY_NOT_COVERED"
                    }
                  },
                  "OWN_REQUEST": {
                    "value": {
                      "message": "Usta kendi talebini alamaz.",
                      "code": "OWN_REQUEST"
                    }
                  },
                  "ALREADY_TAKEN": {
                    "value": {
                      "message": "İş başka bir ustada.",
                      "code": "ALREADY_TAKEN"
                    }
                  },
                  "PENDING_ADMIN_APPROVAL": {
                    "value": {
                      "message": "Hesap çağrı merkezi onayını bekliyor.",
                      "code": "PENDING_ADMIN_APPROVAL"
                    }
                  },
                  "NOT_AVAILABLE_AT_SLOT": {
                    "value": {
                      "message": "Usta o gün ve saatte çalışmıyor.",
                      "code": "NOT_AVAILABLE_AT_SLOT"
                    }
                  },
                  "AREA_NOT_COVERED": {
                    "value": {
                      "message": "Bu bölgede hizmet verilmiyor.",
                      "code": "AREA_NOT_COVERED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `BOOKING_NOT_PAID` — Ödemesi alınmamış iş ustaya verilemez.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "BOOKING_NOT_PAID": {
                    "value": {
                      "message": "Ödemesi alınmamış iş ustaya verilemez.",
                      "code": "BOOKING_NOT_PAID"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "USTA_PROFILE_REQUIRED",
          "SERVICE_CATEGORIES_REQUIRED",
          "CATEGORY_NOT_COVERED",
          "CATEGORY_DOCUMENTS_REQUIRED",
          "CITY_NOT_COVERED",
          "OWN_REQUEST",
          "ALREADY_TAKEN",
          "PENDING_ADMIN_APPROVAL",
          "NOT_AVAILABLE_AT_SLOT",
          "AREA_NOT_COVERED",
          "BOOKING_NOT_PAID"
        ]
      }
    },
    "/jobs/{id}/complete": {
      "post": {
        "operationId": "completeJob",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "İşi tamamla",
        "description": "Bitiş kodu, en az 50 karakterlik not ve 1–5 fotoğrafla işi kapatır; iş müşterinin onayına gider. Aynı gönderimde bir ek ücret de açılabilir.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "description": "Müşteriye gönderilen bitiş kodu (`POST /jobs/{id}/completion-code`).",
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 12
                  },
                  "note": {
                    "description": "Yapılan işin açıklaması, en az 50 karakter.",
                    "type": "string",
                    "minLength": 50,
                    "maxLength": 5000
                  },
                  "photos": {
                    "description": "İşin kanıtı, 1–5 fotoğraf (`POST /uploads/photo`).",
                    "minItems": 1,
                    "maxItems": 5,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "description": "Yüklenen dosyanın adresi.",
                          "type": "string",
                          "minLength": 1
                        },
                        "file_name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mime_type": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "url"
                      ]
                    }
                  },
                  "extra_work": {
                    "description": "İsteğe bağlı: aynı gönderimde bir ek ücret talebi.",
                    "type": "object",
                    "properties": {
                      "line_items": {
                        "maxItems": 10,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "description": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "amount": {
                              "description": "Kalem tutarı, pozitif. Tam TL (750 = ₺750).",
                              "type": "number"
                            }
                          },
                          "required": [
                            "description",
                            "amount"
                          ]
                        }
                      },
                      "note": {
                        "type": "string",
                        "maxLength": 2000
                      },
                      "photos": {
                        "maxItems": 5,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "url": {
                              "description": "Yüklenen dosyanın adresi.",
                              "type": "string",
                              "minLength": 1
                            },
                            "file_name": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "mime_type": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "url"
                          ]
                        }
                      }
                    }
                  }
                },
                "required": [
                  "code",
                  "note",
                  "photos"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "description": "Ustanın gördüğü iş. Kabul etmeden önce yalnızca il ve iş bilgisi; kabul sonrası tam adres ve müşterinin adı (soyadının baş harfi). Telefon hiçbir zaman verilmez: iletişim sohbetten.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    },
                    "extra_work": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "additionalProperties": {}
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "request",
                    "extra_work"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "title": "Klima Bakımı — Standart",
                    "status": "completed",
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "group_siblings": null,
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "base_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "unit_price": 750,
                        "variant_id": "variant_01J00000000000000000000000"
                      }
                    ],
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "amount": 750,
                    "currency_code": "try",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "notes": null,
                    "photos": [],
                    "city": "İstanbul",
                    "district": "Kadıköy",
                    "assigned_usta_id": "cus_01J00000000000000000000000",
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "metadata": {
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "started_at": "2026-10-01T09:00:00.000Z",
                      "on_the_way_at": "2026-10-01T09:00:00.000Z",
                      "ug_pricing_type": "fixed",
                      "ug_fixed_price_checkout": true,
                      "completed_at": "2026-10-01T09:00:00.000Z",
                      "completion_note": "Klima bakımı yapıldı, filtreler temizlendi, gaz basıncı ölçüldü ve dolum tamamlandı.",
                      "completion_photos": [
                        {
                          "url": "https://api.example.com/static/shared/private-1790000000000-ug-cus_01J00000000000000000000000-1790000000000.png"
                        }
                      ]
                    },
                    "address_summary": "Test Sok. 1 D:2",
                    "order_id": null,
                    "customer": null,
                    "customer_id": "cus_01J00000000000000000000000"
                  },
                  "extra_work": null
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `VISIT_CODE_REQUIRED` — Müşterinin okuduğu kodu girin.\n- `VISIT_CODE_INVALID` — Kod yanlış.\n- `INVALID_COMPLETION` — Tamamlama geçersiz: en az 50 karakterlik not ve 1–5 fotoğraf gerekli.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "VISIT_CODE_REQUIRED": {
                    "value": {
                      "message": "Müşterinin okuduğu kodu girin.",
                      "code": "VISIT_CODE_REQUIRED"
                    }
                  },
                  "VISIT_CODE_INVALID": {
                    "value": {
                      "message": "Kod yanlış.",
                      "code": "VISIT_CODE_INVALID"
                    }
                  },
                  "INVALID_COMPLETION": {
                    "value": {
                      "message": "Tamamlama geçersiz: en az 50 karakterlik not ve 1–5 fotoğraf gerekli.",
                      "code": "INVALID_COMPLETION"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `VISIT_CODE_NOT_ISSUED` — Bu adım için kod henüz üretilmedi (önce yola çıkın / kodu gönderin).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VISIT_CODE_NOT_ISSUED": {
                    "value": {
                      "message": "Bu adım için kod henüz üretilmedi (önce yola çıkın / kodu gönderin).",
                      "code": "VISIT_CODE_NOT_ISSUED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "VISIT_CODE_REQUIRED",
          "VISIT_CODE_INVALID",
          "VISIT_CODE_NOT_ISSUED",
          "NOT_FOUND",
          "INVALID_COMPLETION"
        ]
      }
    },
    "/jobs/{id}/completion-code": {
      "post": {
        "operationId": "sendCompletionCode",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "Bitiş kodunu gönder",
        "description": "Müşteriye bitiş kodunu SMS, push ve bildirim olarak gönderir. Tekrar çağrılabilir.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sent": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "sent"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "sent": true
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `NOT_ASSIGNED` — Bu iş size atanmamış.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "NOT_ASSIGNED": {
                    "value": {
                      "message": "Bu iş size atanmamış.",
                      "code": "NOT_ASSIGNED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "NOT_ASSIGNED"
        ]
      }
    },
    "/jobs/{id}/on-the-way": {
      "post": {
        "operationId": "markOnTheWay",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "Yola çıktım",
        "description": "Müşteriye ustanın yolda olduğunu bildirir ve işi başlatacak kodu üretir (kod müşterinin ekranındadır). Tekrar çağrılabilir; aynı kod döner.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "description": "Ustanın gördüğü iş. Kabul etmeden önce yalnızca il ve iş bilgisi; kabul sonrası tam adres ve müşterinin adı (soyadının baş harfi). Telefon hiçbir zaman verilmez: iletişim sohbetten.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "request"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "title": "Klima Bakımı — Standart",
                    "status": "accepted",
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "group_siblings": null,
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "base_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "unit_price": 750,
                        "variant_id": "variant_01J00000000000000000000000"
                      }
                    ],
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "amount": 750,
                    "currency_code": "try",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "notes": null,
                    "photos": [],
                    "city": "İstanbul",
                    "district": "Kadıköy",
                    "assigned_usta_id": "cus_01J00000000000000000000000",
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "metadata": {
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "ug_pricing_type": "fixed",
                      "ug_fixed_price_checkout": true,
                      "on_the_way_at": "2026-10-01T09:00:00.000Z"
                    },
                    "address_summary": "Test Sok. 1 D:2",
                    "order_id": null,
                    "customer": null,
                    "customer_id": "cus_01J00000000000000000000000"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED"
        ]
      }
    },
    "/jobs/{id}/reject": {
      "post": {
        "operationId": "rejectJob",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "İşi reddet",
        "description": "Size gelen teklifi reddeder (iş diğer ustalara açık kalır) ya da üstlendiğiniz işi geri verir.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "description": "Ustanın gördüğü iş. Kabul etmeden önce yalnızca il ve iş bilgisi; kabul sonrası tam adres ve müşterinin adı (soyadının baş harfi). Telefon hiçbir zaman verilmez: iletişim sohbetten.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    },
                    "declined": {
                      "description": "`true`: yalnızca size gelen teklifi reddettiniz, iş başka ustalara açık kalır.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "request"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `USTA_PROFILE_REQUIRED` — Önce usta profili oluşturulmalı.\n- `SERVICE_CATEGORIES_REQUIRED` — En az bir hizmet kategorisi seçilmeli.\n- `CATEGORY_NOT_COVERED` — İş, ustanın kategorileri arasında değil.\n- `CATEGORY_DOCUMENTS_REQUIRED` — Bu kategorinin işleri için onaylı belge gerekiyor.\n- `CITY_NOT_COVERED` — İş, ustanın ilinin dışında.\n- `OWN_REQUEST` — Usta kendi talebini alamaz.\n- `ALREADY_TAKEN` — İş başka bir ustada.\n- `PENDING_ADMIN_APPROVAL` — Hesap çağrı merkezi onayını bekliyor.\n- `NOT_AVAILABLE_AT_SLOT` — Usta o gün ve saatte çalışmıyor.\n- `AREA_NOT_COVERED` — Bu bölgede hizmet verilmiyor.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "USTA_PROFILE_REQUIRED": {
                    "value": {
                      "message": "Önce usta profili oluşturulmalı.",
                      "code": "USTA_PROFILE_REQUIRED"
                    }
                  },
                  "SERVICE_CATEGORIES_REQUIRED": {
                    "value": {
                      "message": "En az bir hizmet kategorisi seçilmeli.",
                      "code": "SERVICE_CATEGORIES_REQUIRED"
                    }
                  },
                  "CATEGORY_NOT_COVERED": {
                    "value": {
                      "message": "İş, ustanın kategorileri arasında değil.",
                      "code": "CATEGORY_NOT_COVERED"
                    }
                  },
                  "CATEGORY_DOCUMENTS_REQUIRED": {
                    "value": {
                      "message": "Bu kategorinin işleri için onaylı belge gerekiyor.",
                      "code": "CATEGORY_DOCUMENTS_REQUIRED"
                    }
                  },
                  "CITY_NOT_COVERED": {
                    "value": {
                      "message": "İş, ustanın ilinin dışında.",
                      "code": "CITY_NOT_COVERED"
                    }
                  },
                  "OWN_REQUEST": {
                    "value": {
                      "message": "Usta kendi talebini alamaz.",
                      "code": "OWN_REQUEST"
                    }
                  },
                  "ALREADY_TAKEN": {
                    "value": {
                      "message": "İş başka bir ustada.",
                      "code": "ALREADY_TAKEN"
                    }
                  },
                  "PENDING_ADMIN_APPROVAL": {
                    "value": {
                      "message": "Hesap çağrı merkezi onayını bekliyor.",
                      "code": "PENDING_ADMIN_APPROVAL"
                    }
                  },
                  "NOT_AVAILABLE_AT_SLOT": {
                    "value": {
                      "message": "Usta o gün ve saatte çalışmıyor.",
                      "code": "NOT_AVAILABLE_AT_SLOT"
                    }
                  },
                  "AREA_NOT_COVERED": {
                    "value": {
                      "message": "Bu bölgede hizmet verilmiyor.",
                      "code": "AREA_NOT_COVERED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "USTA_PROFILE_REQUIRED",
          "SERVICE_CATEGORIES_REQUIRED",
          "CATEGORY_NOT_COVERED",
          "CATEGORY_DOCUMENTS_REQUIRED",
          "CITY_NOT_COVERED",
          "OWN_REQUEST",
          "ALREADY_TAKEN",
          "PENDING_ADMIN_APPROVAL",
          "NOT_AVAILABLE_AT_SLOT",
          "AREA_NOT_COVERED"
        ]
      }
    },
    "/jobs/{id}/start": {
      "post": {
        "operationId": "startJob",
        "tags": [
          "Usta — İşler"
        ],
        "summary": "İşe başla",
        "description": "Müşterinin okuduğu başlangıç koduyla işi başlatır. Kod sunucuda karşılaştırılır; ustaya API'den hiç gönderilmez.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "description": "Müşterinin ekranındaki başlangıç kodu (6 hane; usta yola çıkınca üretilir).",
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 12
                  }
                },
                "required": [
                  "code"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request": {
                      "description": "Ustanın gördüğü iş. Kabul etmeden önce yalnızca il ve iş bilgisi; kabul sonrası tam adres ve müşterinin adı (soyadının baş harfi). Telefon hiçbir zaman verilmez: iletişim sohbetten.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "appointment_date": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "appointment_slot": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "appointment_date",
                        "appointment_slot"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "request"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "request": {
                    "id": "01J00000000000000000000000",
                    "reference": "UG-102610123456",
                    "title": "Klima Bakımı — Standart",
                    "status": "in_progress",
                    "category_handle": "klima",
                    "group_id": null,
                    "group_order": null,
                    "group_siblings": null,
                    "items": [
                      {
                        "title": "Klima Bakımı — Standart",
                        "quantity": 1,
                        "base_price": 750,
                        "product_id": "prod_01J00000000000000000000000",
                        "unit_price": 750,
                        "variant_id": "variant_01J00000000000000000000000"
                      }
                    ],
                    "product_id": "prod_01J00000000000000000000000",
                    "variant_id": "variant_01J00000000000000000000000",
                    "amount": 750,
                    "currency_code": "try",
                    "pricing_type": "fixed",
                    "fixed_price_checkout": true,
                    "appointment_date": "2026-10-06",
                    "appointment_slot": "09:00-11:00",
                    "notes": null,
                    "photos": [],
                    "city": "İstanbul",
                    "district": "Kadıköy",
                    "assigned_usta_id": "cus_01J00000000000000000000000",
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "metadata": {
                      "city": "İstanbul",
                      "district": "Kadıköy",
                      "on_the_way_at": "2026-10-01T09:00:00.000Z",
                      "ug_pricing_type": "fixed",
                      "ug_fixed_price_checkout": true,
                      "started_at": "2026-10-01T09:00:00.000Z"
                    },
                    "address_summary": "Test Sok. 1 D:2",
                    "order_id": null,
                    "customer": null,
                    "customer_id": "cus_01J00000000000000000000000"
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `VISIT_CODE_REQUIRED` — Müşterinin okuduğu kodu girin.\n- `VISIT_CODE_INVALID` — Kod yanlış.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "VISIT_CODE_REQUIRED": {
                    "value": {
                      "message": "Müşterinin okuduğu kodu girin.",
                      "code": "VISIT_CODE_REQUIRED"
                    }
                  },
                  "VISIT_CODE_INVALID": {
                    "value": {
                      "message": "Kod yanlış.",
                      "code": "VISIT_CODE_INVALID"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `VISIT_CODE_NOT_ISSUED` — Bu adım için kod henüz üretilmedi (önce yola çıkın / kodu gönderin).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VISIT_CODE_NOT_ISSUED": {
                    "value": {
                      "message": "Bu adım için kod henüz üretilmedi (önce yola çıkın / kodu gönderin).",
                      "code": "VISIT_CODE_NOT_ISSUED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "VISIT_CODE_REQUIRED",
          "VISIT_CODE_INVALID",
          "VISIT_CODE_NOT_ISSUED"
        ]
      }
    },
    "/legal": {
      "get": {
        "operationId": "getLegalDocuments",
        "tags": [
          "Katalog"
        ],
        "summary": "Sözleşmeleri getir",
        "description": "Yayındaki sözleşme metinleri ve sürümleri. Rezervasyon öncesinde müşteriye gösterip `POST /bookings` isteğinin `legal_acceptance` alanına anahtar ve sürüm yazın; sunucu onay kopyasını kendi doldurur.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "product_ids",
            "in": "query",
            "required": false,
            "description": "Virgülle hizmet kimlikleri: sepetin hizmete özel sözleşme şartları da döner.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "documents": {
                      "description": "Yayındaki sözleşmeler; `POST /bookings` `legal_acceptance` alanına anahtar ve sürüm yazılır.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "version": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "key",
                          "version"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "settings": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "documents",
                    "settings"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/me": {
      "get": {
        "operationId": "getMe",
        "tags": [
          "Hesap"
        ],
        "summary": "Hesabı getir",
        "description": "Anahtarın bağlı olduğu hesap.\n\n**Erişim:** her iki rol · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "customer": {
                      "description": "Anahtarın hesabı.",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    },
                    "role": {
                      "description": "Hesabın birincil rolü.",
                      "type": "string"
                    },
                    "name_locked": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "customer",
                    "role"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/notifications": {
      "get": {
        "operationId": "listNotifications",
        "tags": [
          "Hesap"
        ],
        "summary": "Bildirimleri listele",
        "description": "Hesabın uygulama içi bildirim kutusu, en yeni önce.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "unread",
            "in": "query",
            "required": false,
            "description": "`true`: yalnızca okunmamışlar.",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "notifications": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "unread_count": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "notifications",
                    "unread_count"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/notifications/{id}/read": {
      "post": {
        "operationId": "markNotificationRead",
        "tags": [
          "Hesap"
        ],
        "summary": "Bildirimi okundu işaretle",
        "description": "Tek bir bildirimi okundu yapar.\n\n**Erişim:** her iki rol · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "notification": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "notification"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "write"
      }
    },
    "/notifications/read-all": {
      "post": {
        "operationId": "markAllNotificationsRead",
        "tags": [
          "Hesap"
        ],
        "summary": "Hepsini okundu işaretle",
        "description": "Hesabın bütün bildirimlerini okundu yapar.\n\n**Erişim:** her iki rol · izin `write`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "updated": {}
                  },
                  "required": [
                    "updated"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "write"
      }
    },
    "/notifications/sync": {
      "get": {
        "operationId": "syncNotifications",
        "tags": [
          "Hesap"
        ],
        "summary": "Yeni bildirimleri yokla",
        "description": "İmleçle artımlı okuma: önce `after` olmadan çağırıp imleci alın, sonra her yoklamada önceki cevabın `cursor.at` ve `cursor.ids` değerlerini gönderin. Webhook yerine bunu kullanın.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Önceki cevabın `cursor.at` değeri. Verilmezse yalnızca imleç döner (başlangıç).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "seen",
            "in": "query",
            "required": false,
            "description": "Önceki cevabın `cursor.ids`, virgülle.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "notifications": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "type"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "cursor": {
                      "type": "object",
                      "properties": {
                        "at": {
                          "type": "string"
                        },
                        "ids": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "at",
                        "ids"
                      ],
                      "additionalProperties": {}
                    },
                    "has_more": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "notifications",
                    "cursor",
                    "has_more"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read",
        "x-ai-hint": "Durum değişikliklerini izlemek için 15–60 sn'de bir yoklayın."
      }
    },
    "/payment-methods": {
      "get": {
        "operationId": "getPaymentMethods",
        "tags": [
          "Katalog"
        ],
        "summary": "Ödeme yöntemlerini getir",
        "description": "Şu anda hangi ödeme yöntemlerinin açık olduğu ve havale hesapları. `POST /payments` aynı kararı verir.\n\n**Erişim:** her iki rol · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "card": {
                      "type": "object",
                      "properties": {
                        "available": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "available"
                      ],
                      "additionalProperties": {}
                    },
                    "bank_transfer": {
                      "type": "object",
                      "properties": {
                        "available": {
                          "type": "boolean"
                        },
                        "accounts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {},
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "available",
                        "accounts"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "card",
                    "bank_transfer"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/payments": {
      "get": {
        "operationId": "listPayments",
        "tags": [
          "Ödemeler"
        ],
        "summary": "Ödemeleri listele",
        "description": "`service_request_id` ile bir rezervasyonun ödemeleri; havale bekleniyorsa talimatlar da döner.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "service_request_id",
            "in": "query",
            "required": false,
            "description": "Bir rezervasyonun ödemeleri.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "escrow_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "escrows": {
                      "type": "array",
                      "items": {
                        "description": "Ödeme kaydı (escrow).",
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "description": "`created` (bekliyor) → `held` (tutuldu) → `released_to_technician` | `refunded` | `disputed`.",
                            "type": "string"
                          },
                          "amount": {
                            "type": "number"
                          },
                          "service_request_id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "status",
                          "amount",
                          "service_request_id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "bank_transfer": {
                      "description": "Havale bekleniyorsa talimatlar.",
                      "type": "object",
                      "properties": {},
                      "additionalProperties": {}
                    },
                    "payment": {
                      "description": "Ödemenin nasıl tamamlanacağı.",
                      "type": "object",
                      "properties": {
                        "mode": {
                          "description": "`gateway`: müşteriyi `payment_url`'e yönlendirin, 3D Secure bankada tamamlanır ve ödeme bankanın onayıyla tutulur. `bank_transfer`: `reference` açıklamaya yazılarak `amount` tutarında havale. `mock`: yalnızca test ortamı, ödeme hemen tutuldu.",
                          "type": "string",
                          "enum": [
                            "gateway",
                            "mock",
                            "bank_transfer"
                          ]
                        },
                        "payment_url": {
                          "description": "Yalnızca `gateway`: bankanın ödeme sayfasına açılan adres (tarayıcı ya da WebView).",
                          "type": "string"
                        },
                        "order_number": {
                          "type": "string"
                        },
                        "reference": {
                          "description": "Havale açıklamasına yazılacak talep numarası.",
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        },
                        "accounts": {
                          "description": "Havale yapılabilecek hesaplar.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "iban": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "iban"
                            ],
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "mode"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "escrows"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "escrows": [
                    {
                      "id": "01J00000000000000000000000",
                      "order_id": null,
                      "service_request_id": "01J00000000000000000000000",
                      "customer_id": "cus_01J00000000000000000000000",
                      "usta_id": null,
                      "kind": "primary",
                      "extra_work_id": null,
                      "amount": 750,
                      "currency_code": "try",
                      "commission_rate": 0.15,
                      "commission_amount": 112,
                      "payout_amount": 638,
                      "refunded_amount": 0,
                      "status": "held",
                      "provider": "card-mock",
                      "payment_session_id": null,
                      "transaction_id": "MOCK-01J00000000000000000000000",
                      "released_at": null,
                      "held_at": "2026-10-01T09:00:00.000Z",
                      "disputed_at": null,
                      "dispute_reason": null,
                      "refund_requested_at": null,
                      "refunded_at": null,
                      "refund_reason": null,
                      "refund_reference": null,
                      "refund_channel": null,
                      "refund_ticket_id": null,
                      "metadata": {
                        "commission_source": "services"
                      },
                      "created_at": "2026-10-01T09:00:00.000Z",
                      "updated_at": "2026-10-01T09:00:00.000Z",
                      "deleted_at": null
                    }
                  ],
                  "role": "customer"
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "createPayment",
        "tags": [
          "Ödemeler"
        ],
        "summary": "Ödeme aç",
        "description": "Bir rezervasyonun (bacağın) ödemesini açar; tutar sunucunun hesapladığı tutardır, istemciden alınmaz. `payment.mode`: `gateway` → müşteriyi `payment_url`'e yönlendirin; `bank_transfer` → talimatları gösterin (ekip havaleyi görünce ödeme tutulur); `mock` → yalnızca test ortamı. Ödeme tutulunca iş ustalara dağıtılır. Gruplu rezervasyonda her bacak için çağırın; kartla tek çekim ilk bacaktan yapılır. Rezervasyon başına tek ödeme: ikinci çağrı 409 `ESCROW_EXISTS` ve mevcut kaydı döner.\n\n**Erişim:** müşteri anahtarı · izin `money`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "service_request_id": {
                    "description": "Ödenecek rezervasyon (bacak).",
                    "type": "string",
                    "minLength": 1
                  },
                  "payment_method": {
                    "description": "`card` (varsayılan) ya da `bank_transfer`.",
                    "type": "string",
                    "enum": [
                      "card",
                      "bank_transfer"
                    ]
                  }
                },
                "required": [
                  "service_request_id"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "escrow": {
                      "description": "Ödeme kaydı (escrow).",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`created` (bekliyor) → `held` (tutuldu) → `released_to_technician` | `refunded` | `disputed`.",
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    },
                    "payment": {
                      "description": "Ödemenin nasıl tamamlanacağı.",
                      "type": "object",
                      "properties": {
                        "mode": {
                          "description": "`gateway`: müşteriyi `payment_url`'e yönlendirin, 3D Secure bankada tamamlanır ve ödeme bankanın onayıyla tutulur. `bank_transfer`: `reference` açıklamaya yazılarak `amount` tutarında havale. `mock`: yalnızca test ortamı, ödeme hemen tutuldu.",
                          "type": "string",
                          "enum": [
                            "gateway",
                            "mock",
                            "bank_transfer"
                          ]
                        },
                        "payment_url": {
                          "description": "Yalnızca `gateway`: bankanın ödeme sayfasına açılan adres (tarayıcı ya da WebView).",
                          "type": "string"
                        },
                        "order_number": {
                          "type": "string"
                        },
                        "reference": {
                          "description": "Havale açıklamasına yazılacak talep numarası.",
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        },
                        "accounts": {
                          "description": "Havale yapılabilecek hesaplar.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "iban": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "iban"
                            ],
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "mode"
                      ],
                      "additionalProperties": {}
                    },
                    "group": {
                      "description": "Gruplu rezervasyonda bütün bacakların dökümü ve toplamı.",
                      "type": "object",
                      "properties": {
                        "group_id": {
                          "type": "string"
                        },
                        "total": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "group_id",
                        "total"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "escrow",
                    "payment"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "escrow": {
                    "id": "01J00000000000000000000000",
                    "order_id": null,
                    "service_request_id": "01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "usta_id": null,
                    "kind": "primary",
                    "extra_work_id": null,
                    "amount": 750,
                    "currency_code": "try",
                    "commission_rate": 0.15,
                    "commission_amount": 112,
                    "payout_amount": 638,
                    "refunded_amount": 0,
                    "status": "held",
                    "provider": "card-mock",
                    "payment_session_id": null,
                    "transaction_id": "MOCK-01J00000000000000000000000",
                    "released_at": null,
                    "held_at": "2026-10-01T09:00:00.000Z",
                    "disputed_at": null,
                    "dispute_reason": null,
                    "refund_requested_at": null,
                    "refunded_at": null,
                    "refund_reason": null,
                    "refund_reference": null,
                    "refund_channel": null,
                    "refund_ticket_id": null,
                    "metadata": {
                      "commission_source": "services"
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  },
                  "payment": {
                    "mode": "mock"
                  },
                  "dispatch": {
                    "dispatched": false,
                    "offer_count": 0,
                    "note": "no_matching_usta"
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `AMOUNT_NOT_SET` — Talebin tutarı henüz belli değil (keşifli iş: önce bir teklif kabul edilmeli).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "AMOUNT_NOT_SET": {
                    "value": {
                      "message": "Talebin tutarı henüz belli değil (keşifli iş: önce bir teklif kabul edilmeli).",
                      "code": "AMOUNT_NOT_SET"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `ESCROW_EXISTS` — Bu talep için zaten bir ödeme kaydı var; mevcut kayıt `escrow` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "ESCROW_EXISTS": {
                    "value": {
                      "message": "Bu talep için zaten bir ödeme kaydı var; mevcut kayıt `escrow` alanında.",
                      "code": "ESCROW_EXISTS"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Hizmet yapılandırılmamış.\n\n- `PAYMENT_GATEWAY_UNCONFIGURED` — Kartla ödeme şu anda kullanılamıyor.\n- `BANK_TRANSFER_UNCONFIGURED` — Havale şu anda kullanılamıyor.\n- `HOSTED_PAYMENT_UNAVAILABLE` — Kartla ödeme bu kanaldan henüz açık değil; havale kullanın.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PAYMENT_GATEWAY_UNCONFIGURED": {
                    "value": {
                      "message": "Kartla ödeme şu anda kullanılamıyor.",
                      "code": "PAYMENT_GATEWAY_UNCONFIGURED"
                    }
                  },
                  "BANK_TRANSFER_UNCONFIGURED": {
                    "value": {
                      "message": "Havale şu anda kullanılamıyor.",
                      "code": "BANK_TRANSFER_UNCONFIGURED"
                    }
                  },
                  "HOSTED_PAYMENT_UNAVAILABLE": {
                    "value": {
                      "message": "Kartla ödeme bu kanaldan henüz açık değil; havale kullanın.",
                      "code": "HOSTED_PAYMENT_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "money",
        "x-ug-error-codes": [
          "ESCROW_EXISTS",
          "AMOUNT_NOT_SET",
          "PAYMENT_GATEWAY_UNCONFIGURED",
          "BANK_TRANSFER_UNCONFIGURED",
          "HOSTED_PAYMENT_UNAVAILABLE"
        ],
        "x-ai-hint": "Kart için `payment_url`'i müşteriye verin; kart bilgisi asla bu API'ye gönderilmez."
      }
    },
    "/payments/{id}/dispute": {
      "post": {
        "operationId": "disputePayment",
        "tags": [
          "Ödemeler"
        ],
        "summary": "Anlaşmazlık aç",
        "description": "Tutulan bir ödemeyi dondurur ve ekibe bir anlaşmazlık bileti açar; yalnızca iş başladıktan sonra ve onaydan önce. Ekip kararına göre ödeme ustaya bırakılır ya da iade edilir.\n\n**Erişim:** müşteri anahtarı · izin `money`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "description": "Anlaşmazlığın açıklaması, 50–500 karakter.",
                    "type": "string",
                    "minLength": 50,
                    "maxLength": 500
                  }
                },
                "required": [
                  "reason"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "escrow": {
                      "description": "Ödeme kaydı (escrow).",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`created` (bekliyor) → `held` (tutuldu) → `released_to_technician` | `refunded` | `disputed`.",
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    },
                    "ticket": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "escrow",
                    "ticket"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `DISPUTE_STATEMENT_INVALID` — Anlaşmazlık açıklaması 50–500 karakter olmalı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "DISPUTE_STATEMENT_INVALID": {
                    "value": {
                      "message": "Anlaşmazlık açıklaması 50–500 karakter olmalı.",
                      "code": "DISPUTE_STATEMENT_INVALID"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `DISPUTE_NOT_HELD` — Bu ödeme için anlaşmazlık açılamaz.\n- `DISPUTE_REFUND_PENDING` — Bekleyen bir iade talebi var.\n- `DISPUTE_TOO_EARLY` — İş başlamadan anlaşmazlık açılamaz.\n- `DISPUTE_ALREADY_CONFIRMED` — Onaylanmış bir iş için anlaşmazlık açılamaz.\n- `DISPUTE_ALREADY_DISPUTED` — Zaten açık bir anlaşmazlık var.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "DISPUTE_NOT_HELD": {
                    "value": {
                      "message": "Bu ödeme için anlaşmazlık açılamaz.",
                      "code": "DISPUTE_NOT_HELD"
                    }
                  },
                  "DISPUTE_REFUND_PENDING": {
                    "value": {
                      "message": "Bekleyen bir iade talebi var.",
                      "code": "DISPUTE_REFUND_PENDING"
                    }
                  },
                  "DISPUTE_TOO_EARLY": {
                    "value": {
                      "message": "İş başlamadan anlaşmazlık açılamaz.",
                      "code": "DISPUTE_TOO_EARLY"
                    }
                  },
                  "DISPUTE_ALREADY_CONFIRMED": {
                    "value": {
                      "message": "Onaylanmış bir iş için anlaşmazlık açılamaz.",
                      "code": "DISPUTE_ALREADY_CONFIRMED"
                    }
                  },
                  "DISPUTE_ALREADY_DISPUTED": {
                    "value": {
                      "message": "Zaten açık bir anlaşmazlık var.",
                      "code": "DISPUTE_ALREADY_DISPUTED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "money",
        "x-ug-error-codes": [
          "DISPUTE_STATEMENT_INVALID",
          "DISPUTE_NOT_HELD",
          "DISPUTE_REFUND_PENDING",
          "DISPUTE_TOO_EARLY",
          "DISPUTE_ALREADY_CONFIRMED",
          "DISPUTE_ALREADY_DISPUTED"
        ]
      }
    },
    "/payments/{id}/refund": {
      "post": {
        "operationId": "requestRefund",
        "tags": [
          "Ödemeler"
        ],
        "summary": "İade iste",
        "description": "İade talebi açar (202); parayı ekip iade eder. Talep açıkken iş onaylanamaz.\n\n**Erişim:** müşteri anahtarı · izin `money`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "description": "İade gerekçesi.",
                    "type": "string",
                    "minLength": 1
                  },
                  "amount": {
                    "description": "İsteğe bağlı kısmi iade; verilmezse kalan tutarın tamamı. Tam TL (750 = ₺750).",
                    "type": "number"
                  }
                },
                "required": [
                  "reason"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ticket": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    },
                    "escrow": {
                      "description": "Ödeme kaydı (escrow).",
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`created` (bekliyor) → `held` (tutuldu) → `released_to_technician` | `refunded` | `disputed`.",
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        },
                        "service_request_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount",
                        "service_request_id"
                      ],
                      "additionalProperties": {}
                    },
                    "requested_amount": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "ticket",
                    "escrow",
                    "requested_amount"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `REFUND_REASON_REQUIRED` — İade gerekçesi zorunlu.\n- `REFUND_AMOUNT_INVALID` — İade tutarı geçersiz ya da iade edilebilir tutarı aşıyor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "REFUND_REASON_REQUIRED": {
                    "value": {
                      "message": "İade gerekçesi zorunlu.",
                      "code": "REFUND_REASON_REQUIRED"
                    }
                  },
                  "REFUND_AMOUNT_INVALID": {
                    "value": {
                      "message": "İade tutarı geçersiz ya da iade edilebilir tutarı aşıyor.",
                      "code": "REFUND_AMOUNT_INVALID"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `ESCROW_DISPUTED` — Ödeme için açık bir anlaşmazlık var.\n- `ESCROW_NOT_REFUNDABLE` — Bu ödeme iade edilebilir durumda değil.\n- `REFUND_ALREADY_REQUESTED` — Bu ödeme için zaten bir iade talebi var.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "ESCROW_DISPUTED": {
                    "value": {
                      "message": "Ödeme için açık bir anlaşmazlık var.",
                      "code": "ESCROW_DISPUTED"
                    }
                  },
                  "ESCROW_NOT_REFUNDABLE": {
                    "value": {
                      "message": "Bu ödeme iade edilebilir durumda değil.",
                      "code": "ESCROW_NOT_REFUNDABLE"
                    }
                  },
                  "REFUND_ALREADY_REQUESTED": {
                    "value": {
                      "message": "Bu ödeme için zaten bir iade talebi var.",
                      "code": "REFUND_ALREADY_REQUESTED"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "money",
        "x-ug-error-codes": [
          "REFUND_REASON_REQUIRED",
          "REFUND_AMOUNT_INVALID",
          "ESCROW_DISPUTED",
          "ESCROW_NOT_REFUNDABLE",
          "REFUND_ALREADY_REQUESTED"
        ]
      }
    },
    "/payouts": {
      "get": {
        "operationId": "listPayouts",
        "tags": [
          "Usta — Hakediş"
        ],
        "summary": "Hakedişleri listele",
        "description": "Haftalık hakediş dökümleri, en yeni önce.\n\n**Erişim:** usta anahtarı · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payouts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "description": "`pending_approval` → `approved` (ustanın onayı) → `paid` (ekip havaleyi yaptı).",
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "status"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "payouts"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read"
      }
    },
    "/payouts/{id}": {
      "get": {
        "operationId": "getPayout",
        "tags": [
          "Usta — Hakediş"
        ],
        "summary": "Hakedişi getir",
        "description": "Tek hakediş ve kalemleri.\n\n**Erişim:** usta anahtarı · izin `read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payout": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_approval` → `approved` (ustanın onayı) → `paid` (ekip havaleyi yaptı).",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status"
                      ],
                      "additionalProperties": {}
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": {}
                      }
                    },
                    "payment_delay_days": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "payout",
                    "items",
                    "payment_delay_days"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read"
      }
    },
    "/payouts/{id}/approve": {
      "post": {
        "operationId": "approvePayout",
        "tags": [
          "Usta — Hakediş"
        ],
        "summary": "Hakedişi onayla",
        "description": "Dökümü onaylar; ödeme vade tarihinde ekip tarafından yapılır. Geçerli bir IBAN gerekir.\n\n**Erişim:** usta anahtarı · izin `money`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payout": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "description": "`pending_approval` → `approved` (ustanın onayı) → `paid` (ekip havaleyi yaptı).",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "status"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "payout"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kaydın şu anki durumu bu işleme izin vermiyor.\n\n- `PAYOUT_DETAILS_REQUIRED` — Hakediş için geçerli bir IBAN gerekli.\n- `INVALID_STATUS` — Kaydın durumu buna izin vermiyor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PAYOUT_DETAILS_REQUIRED": {
                    "value": {
                      "message": "Hakediş için geçerli bir IBAN gerekli.",
                      "code": "PAYOUT_DETAILS_REQUIRED"
                    }
                  },
                  "INVALID_STATUS": {
                    "value": {
                      "message": "Kaydın durumu buna izin vermiyor.",
                      "code": "INVALID_STATUS"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "money",
        "x-ug-error-codes": [
          "PAYOUT_DETAILS_REQUIRED",
          "INVALID_STATUS"
        ]
      }
    },
    "/pricing/preview": {
      "post": {
        "operationId": "previewPricing",
        "tags": [
          "Katalog"
        ],
        "summary": "Sepeti fiyatla",
        "description": "Rezervasyon uçlarının kendi koduyla sepeti fiyatlar ama hiçbir kayıt açmaz: bölge fiyatı, soru cevaplarının farkı ve toplam. Müşteriye göstereceğiniz tutar budur; `POST /bookings` aynı tutarı hesaplar.\n\n**Erişim:** her iki rol · izin `read`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "description": "Fiyatlanacak hizmetler (1–50).",
                    "minItems": 1,
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "variant_id": {
                          "description": "Paket (varyant) kimliği. Verilmezse hizmetin en ucuz paketi.",
                          "type": "string",
                          "minLength": 1
                        },
                        "product_id": {
                          "description": "Hizmet (ürün) kimliği; `variant_id` yoksa zorunlu.",
                          "type": "string",
                          "minLength": 1
                        },
                        "quantity": {
                          "description": "Adet, 1–99. Varsayılan 1.",
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 99
                        },
                        "answers": {
                          "description": "Hizmet sorularının cevapları (`ug_service_questions`). Fiyat farkı katalogdan hesaplanır, istemciden gelmez; zorunlu soru boşsa 400 `INVALID_SERVICE_ANSWER`.",
                          "maxItems": 20,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "question_id": {
                                "description": "Sorunun kimliği.",
                                "type": "string",
                                "minLength": 1
                              },
                              "option_ids": {
                                "description": "Seçim sorularında işaretlenen seçenekler.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "text": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "number": {
                                "anyOf": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "photos": {
                                "description": "Fotoğraf sorusu: `POST /uploads/photo` adresleri.",
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "entry_id": {
                                "description": "Katalog sorusu (marka/model): `GET /reference-catalogs/{key}` girdisinin kimliği.",
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "entry_label": {
                                "anyOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "question_id"
                            ]
                          }
                        }
                      }
                    }
                  },
                  "city": {
                    "description": "İl (ör. `İstanbul`). Bölge fiyatı il/ilçeye göre uygulanır.",
                    "type": "string"
                  },
                  "district": {
                    "description": "İlçe (ör. `Kadıköy`).",
                    "type": "string"
                  }
                },
                "required": [
                  "items"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "title": {
                            "type": "string"
                          },
                          "unit_price": {
                            "type": "number"
                          },
                          "quantity": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "title",
                          "unit_price",
                          "quantity"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "total": {
                      "description": "Toplam, tam TL.",
                      "type": "number"
                    },
                    "currency_code": {
                      "type": "string",
                      "const": "try"
                    },
                    "priced_by_zone": {
                      "description": "En az bir kalem bölge fiyatıyla fiyatlandıysa `true`.",
                      "type": "boolean"
                    },
                    "location": {
                      "type": "object",
                      "properties": {},
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "items",
                    "total",
                    "currency_code",
                    "priced_by_zone",
                    "location"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "items": [
                    {
                      "title": "Klima Bakımı — Standart",
                      "quantity": 1,
                      "unit_price": 750,
                      "product_id": "prod_01J00000000000000000000000",
                      "variant_id": "variant_01J00000000000000000000000",
                      "base_price": 750
                    }
                  ],
                  "total": 750,
                  "currency_code": "try",
                  "location": {
                    "city": "İstanbul",
                    "district": "Kadıköy",
                    "zone_key": "istanbul/kadikoy"
                  },
                  "priced_by_zone": false
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `EMPTY_ITEMS` — Fiyatlanacak hizmet yok.\n- `INVALID_SERVICE_ANSWER` — Hizmet sorularının cevabı eksik ya da geçersiz; ayrıntı `errors` alanında.\n- `INVALID_SERVICE_ITEM` — Hizmet bulunamadı ya da yayında değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "EMPTY_ITEMS": {
                    "value": {
                      "message": "Fiyatlanacak hizmet yok.",
                      "code": "EMPTY_ITEMS"
                    }
                  },
                  "INVALID_SERVICE_ANSWER": {
                    "value": {
                      "message": "Hizmet sorularının cevabı eksik ya da geçersiz; ayrıntı `errors` alanında.",
                      "code": "INVALID_SERVICE_ANSWER"
                    }
                  },
                  "INVALID_SERVICE_ITEM": {
                    "value": {
                      "message": "Hizmet bulunamadı ya da yayında değil.",
                      "code": "INVALID_SERVICE_ITEM"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read",
        "x-ug-error-codes": [
          "EMPTY_ITEMS",
          "INVALID_SERVICE_ANSWER",
          "INVALID_SERVICE_ITEM"
        ]
      }
    },
    "/quotes": {
      "get": {
        "operationId": "listQuotes",
        "tags": [
          "Teklifler"
        ],
        "summary": "Teklifleri listele",
        "description": "Keşifli işlerin teklifleri; müşteri taslakları görmez.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "service_request_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "quotes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "id",
                          "status",
                          "amount"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "role": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "quotes",
                    "role"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "createQuote",
        "tags": [
          "Teklifler"
        ],
        "summary": "Teklif ver",
        "description": "Keşifli bir işe fiyat teklifi verir; tutar hizmetin fiyat aralığında olmalı. Varsayılan olarak hemen gönderilir.\n\n**Erişim:** usta anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "service_request_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "amount": {
                    "description": "Teklif tutarı, hizmetin fiyat aralığında. Tam TL (750 = ₺750).",
                    "type": "number"
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "send": {
                    "description": "`false`: taslak olarak kaydet (varsayılan: hemen gönder).",
                    "type": "boolean"
                  }
                },
                "required": [
                  "service_request_id",
                  "amount"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "quote": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "quote"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "quote": {
                    "id": "01J00000000000000000000000",
                    "service_request_id": "01J00000000000000000000000",
                    "usta_id": "cus_01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "amount": 1500,
                    "currency_code": "try",
                    "notes": "Keşif",
                    "status": "sent",
                    "metadata": {
                      "ug_min_price": null,
                      "ug_max_price": null
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `FIXED_PRICE_PATH` — Sabit fiyatlı işe teklif verilmez.\n- `QUOTE_CREATE_FAILED` — Teklif oluşturulamadı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "FIXED_PRICE_PATH": {
                    "value": {
                      "message": "Sabit fiyatlı işe teklif verilmez.",
                      "code": "FIXED_PRICE_PATH"
                    }
                  },
                  "QUOTE_CREATE_FAILED": {
                    "value": {
                      "message": "Teklif oluşturulamadı.",
                      "code": "QUOTE_CREATE_FAILED"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "İşlenemeyen istek.\n\n- `PRICE_OUT_OF_RANGE` — Teklif hizmetin fiyat aralığının dışında (`min_price`, `max_price`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PRICE_OUT_OF_RANGE": {
                    "value": {
                      "message": "Teklif hizmetin fiyat aralığının dışında (`min_price`, `max_price`).",
                      "code": "PRICE_OUT_OF_RANGE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "FIXED_PRICE_PATH",
          "PRICE_OUT_OF_RANGE",
          "QUOTE_CREATE_FAILED"
        ]
      }
    },
    "/quotes/{id}/accept": {
      "post": {
        "operationId": "acceptQuote",
        "tags": [
          "Teklifler"
        ],
        "summary": "Teklifi kabul et",
        "description": "Teklifi kabul eder; teklif tutarı rezervasyonun tutarı olur. Ardından `POST /payments`.\n\n**Erişim:** müşteri anahtarı · izin `money`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "quote": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "quote"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "quote": {
                    "id": "01J00000000000000000000000",
                    "service_request_id": "01J00000000000000000000000",
                    "usta_id": "cus_01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "amount": 1500,
                    "currency_code": "try",
                    "notes": "Keşif",
                    "status": "accepted",
                    "metadata": {
                      "ug_max_price": null,
                      "ug_min_price": null
                    },
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "money"
      }
    },
    "/quotes/{id}/reject": {
      "post": {
        "operationId": "rejectQuote",
        "tags": [
          "Teklifler"
        ],
        "summary": "Teklifi reddet",
        "description": "Teklifi reddeder.\n\n**Erişim:** müşteri anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "quote": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "quote"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "write"
      }
    },
    "/quotes/{id}/send": {
      "post": {
        "operationId": "sendQuote",
        "tags": [
          "Teklifler"
        ],
        "summary": "Taslak teklifi gönder",
        "description": "Taslak olarak kaydedilen teklifi müşteriye gönderir.\n\n**Erişim:** usta anahtarı · izin `write`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "quote": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "id",
                        "status",
                        "amount"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "quote"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write"
      }
    },
    "/ratings": {
      "get": {
        "operationId": "listRatings",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "Puanları getir",
        "description": "`service_request_id` ile bir işin puanı, `usta_id` ile bir ustanın herkese açık puanları ve ortalaması.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "service_request_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "usta_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rating": {},
                    "ratings": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": {}
                      }
                    },
                    "summary": {}
                  },
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "rateBooking",
        "tags": [
          "Rezervasyonlar"
        ],
        "summary": "İşi puanla",
        "description": "İş başına bir kez: usta puanı (usta sıralamasını besler) ve ayrı bir uygulama puanı.\n\n**Erişim:** müşteri anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "service_request_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "rating": {
                    "description": "Usta puanı, 1–5.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5
                  },
                  "comment": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "app_rating": {
                    "description": "Uygulama puanı, 1–5 (usta sırasını etkilemez).",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5
                  },
                  "app_comment": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "would_rebook": {
                    "type": "boolean"
                  },
                  "would_recommend": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "service_request_id",
                  "rating"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rating": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "rating"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "rating": {
                    "id": "01J00000000000000000000000",
                    "order_id": null,
                    "service_request_id": "01J00000000000000000000000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "usta_id": "cus_01J00000000000000000000000",
                    "rating": 5,
                    "comment": null,
                    "app_rating": 4,
                    "app_comment": null,
                    "would_rebook": null,
                    "would_recommend": null,
                    "metadata": null,
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "customer",
        "x-ug-scope": "write"
      }
    },
    "/reference-catalogs/{key}": {
      "get": {
        "operationId": "getReferenceCatalog",
        "tags": [
          "Katalog"
        ],
        "summary": "Referans kataloğunu getir",
        "description": "Katalog sorularının (ör. klima markası ve modeli) seçenek listesi. `entries` ağaçtır: `parent_id` modeli markaya bağlar. Cevapta `entry_id` olarak kullanılır.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "catalog": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "key": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "key",
                        "name"
                      ],
                      "additionalProperties": {}
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "catalog",
                    "entries"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read",
        "x-ug-error-codes": [
          "NOT_FOUND"
        ]
      }
    },
    "/shop": {
      "get": {
        "operationId": "getShop",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Dükkânı getir",
        "description": "Ustanın dükkân (profil) kaydı.\n\n**Erişim:** usta anahtarı · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shops": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "is_active": {
                            "description": "Çağrı merkezi onayladıysa `true`; yalnızca onaylı ustalar iş alır.",
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "is_active"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "shops"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "saveShop",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Dükkânı kaydet",
        "description": "Dükkânı açar ya da günceller. Yeni dükkân çağrı merkezi onayına kadar iş almaz. Ad, fotoğraf ve tanıtım değişiklikleri ekip onayına düşer.\n\n**Erişim:** usta anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "İşletme adı.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "city": {
                    "type": "string"
                  },
                  "district": {
                    "type": "string"
                  },
                  "service_handles": {
                    "description": "Verilen hizmet kategorilerinin `handle` değerleri (`GET /catalog`).",
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "service_districts": {
                    "maxItems": 200,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 120
                    }
                  },
                  "service_product_ids": {
                    "maxItems": 200,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 120
                    }
                  },
                  "business_profile": {
                    "type": "object",
                    "properties": {
                      "team_size": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 500
                      },
                      "can_issue_invoice": {
                        "type": "boolean"
                      },
                      "has_mastery_certificate": {
                        "type": "boolean"
                      },
                      "employees_insured": {
                        "description": "Yalnızca `team_size > 0` iken zorunlu.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "team_size",
                      "can_issue_invoice",
                      "has_mastery_certificate"
                    ]
                  },
                  "iban": {
                    "description": "TR IBAN; hesap sahibi usta ya da işletme olmalı.",
                    "type": "string"
                  },
                  "iban_holder": {
                    "type": "string"
                  },
                  "tax_number": {
                    "type": "string"
                  },
                  "avatar_url": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shop": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "is_active": {
                          "description": "Çağrı merkezi onayladıysa `true`; yalnızca onaylı ustalar iş alır.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "is_active"
                      ],
                      "additionalProperties": {}
                    },
                    "pending_review": {
                      "description": "Ekip onayına düşen alanlar (ad, fotoğraf, tanıtım); onaylanana kadar müşteri eskisini görür.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "shop"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `INVALID_BUSINESS_PROFILE` — İşletme bilgileri eksik ya da geçersiz.\n- `INVALID_IBAN` — IBAN geçersiz.\n- `IBAN_HOLDER_REQUIRED` — Hesap sahibinin adı zorunlu.\n- `IBAN_HOLDER_MISMATCH` — Hesap sahibi ustanın kendisi ya da işletme adı olmalı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "INVALID_BUSINESS_PROFILE": {
                    "value": {
                      "message": "İşletme bilgileri eksik ya da geçersiz.",
                      "code": "INVALID_BUSINESS_PROFILE"
                    }
                  },
                  "INVALID_IBAN": {
                    "value": {
                      "message": "IBAN geçersiz.",
                      "code": "INVALID_IBAN"
                    }
                  },
                  "IBAN_HOLDER_REQUIRED": {
                    "value": {
                      "message": "Hesap sahibinin adı zorunlu.",
                      "code": "IBAN_HOLDER_REQUIRED"
                    }
                  },
                  "IBAN_HOLDER_MISMATCH": {
                    "value": {
                      "message": "Hesap sahibi ustanın kendisi ya da işletme adı olmalı.",
                      "code": "IBAN_HOLDER_MISMATCH"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `USTA_ROLE_REQUIRED` — Usta rolü gerekli.\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "USTA_ROLE_REQUIRED": {
                    "value": {
                      "message": "Usta rolü gerekli.",
                      "code": "USTA_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "USTA_ROLE_REQUIRED",
          "INVALID_BUSINESS_PROFILE",
          "INVALID_IBAN",
          "IBAN_HOLDER_REQUIRED",
          "IBAN_HOLDER_MISMATCH"
        ]
      }
    },
    "/shop/availability": {
      "get": {
        "operationId": "getAvailability",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Çalışma saatlerini getir",
        "description": "Haftalık çalışma dilimleri ve tarihe özel istisnalar.\n\n**Erişim:** usta anahtarı · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "availability": {
                      "type": "object",
                      "properties": {
                        "configured": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "configured"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "availability"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read",
        "x-ug-error-codes": [
          "NOT_FOUND"
        ]
      },
      "put": {
        "operationId": "setAvailability",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Çalışma saatlerini kaydet",
        "description": "Haftalık dilimleri ve istisnaları yazar; geçersiz girdiler düşürülür. İş eşleşmesi bu takvime göre yapılır.\n\n**Erişim:** usta anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "weekly": {
                    "description": "Haftanın günü (`0` pazar … `6` cumartesi) → çalışılan dilimler.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "pattern": "^[0-6]$"
                    },
                    "additionalProperties": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "overrides": {
                    "description": "Tarihe özel istisnalar.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                    },
                    "additionalProperties": {
                      "type": "object",
                      "properties": {
                        "off": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "extra": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "full_day_off": {
                          "type": "boolean"
                        }
                      }
                    }
                  },
                  "preset": {
                    "type": "string",
                    "enum": [
                      "every_day",
                      "weekdays",
                      "weekends",
                      "custom"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "availability": {
                      "type": "object",
                      "properties": {
                        "configured": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "configured"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "availability"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "NOT_FOUND"
        ]
      }
    },
    "/shop/documents": {
      "get": {
        "operationId": "listDocuments",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Belgeleri listele",
        "description": "Yüklenen belgeler ve ekip kararları.\n\n**Erişim:** usta anahtarı · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "documents": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "documents"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "createDocument",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Belge kaydı ekle",
        "description": "Önceden yüklenmiş özel bir dosyayı belge olarak kaydeder.\n\n**Erişim:** usta anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "doc_type": {
                    "type": "string",
                    "enum": [
                      "myk",
                      "craft_cert",
                      "other"
                    ]
                  },
                  "file_url": {
                    "description": "Bu hesabın özel katmana yüklediği dosyanın adresi. Çoğu durumda `POST /shop/documents/upload` daha basit.",
                    "type": "string",
                    "minLength": 1
                  },
                  "file_name": {
                    "type": "string"
                  },
                  "mime_type": {
                    "type": "string"
                  }
                },
                "required": [
                  "doc_type",
                  "file_url"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "document"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `UNSUPPORTED_FILE_URL` — Dosya adresi bu hesaba ait bir yükleme değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "UNSUPPORTED_FILE_URL": {
                    "value": {
                      "message": "Dosya adresi bu hesaba ait bir yükleme değil.",
                      "code": "UNSUPPORTED_FILE_URL"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `SHOP_NOT_FOUND` — Usta dükkânı bulunamadı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "SHOP_NOT_FOUND": {
                    "value": {
                      "message": "Usta dükkânı bulunamadı.",
                      "code": "SHOP_NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "SHOP_NOT_FOUND",
          "UNSUPPORTED_FILE_URL"
        ]
      }
    },
    "/shop/documents/upload": {
      "post": {
        "operationId": "uploadDocument",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Belge yükle",
        "description": "MYK ya da ustalık belgesini yükler; bazı kategorilerin işleri onaylı belge ister.\n\n**Erişim:** usta anahtarı · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "doc_type": {
                    "description": "`myk` (MYK belgesi), `craft_cert` (ustalık belgesi), `other`.",
                    "type": "string",
                    "enum": [
                      "myk",
                      "craft_cert",
                      "other"
                    ]
                  },
                  "content": {
                    "description": "Base64 dosya, en çok 8 MB.",
                    "type": "string",
                    "minLength": 1
                  },
                  "mime_type": {
                    "type": "string",
                    "enum": [
                      "image/jpeg",
                      "image/png",
                      "image/heic",
                      "image/webp",
                      "application/pdf"
                    ]
                  },
                  "file_name": {
                    "type": "string"
                  },
                  "category_handle": {
                    "description": "Belge bir mesleğe aitse o kategorinin `handle`'ı.",
                    "type": "string"
                  }
                },
                "required": [
                  "doc_type",
                  "content"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "document"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `INVALID_DOC_TYPE` — Belge türü geçersiz (`myk`, `craft_cert`, `other`).\n- `UNSUPPORTED_MIME` — Dosya türü desteklenmiyor.\n- `FILE_TOO_LARGE` — Dosya en çok 8 MB olabilir.\n- `INVALID_DOCUMENT_CATEGORY` — Belge yalnızca ustanın kategorilerinden biri için yüklenebilir.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "INVALID_DOC_TYPE": {
                    "value": {
                      "message": "Belge türü geçersiz (`myk`, `craft_cert`, `other`).",
                      "code": "INVALID_DOC_TYPE"
                    }
                  },
                  "UNSUPPORTED_MIME": {
                    "value": {
                      "message": "Dosya türü desteklenmiyor.",
                      "code": "UNSUPPORTED_MIME"
                    }
                  },
                  "FILE_TOO_LARGE": {
                    "value": {
                      "message": "Dosya en çok 8 MB olabilir.",
                      "code": "FILE_TOO_LARGE"
                    }
                  },
                  "INVALID_DOCUMENT_CATEGORY": {
                    "value": {
                      "message": "Belge yalnızca ustanın kategorilerinden biri için yüklenebilir.",
                      "code": "INVALID_DOCUMENT_CATEGORY"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `SHOP_NOT_FOUND` — Usta dükkânı bulunamadı.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "SHOP_NOT_FOUND": {
                    "value": {
                      "message": "Usta dükkânı bulunamadı.",
                      "code": "SHOP_NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "INVALID_DOC_TYPE",
          "UNSUPPORTED_MIME",
          "FILE_TOO_LARGE",
          "SHOP_NOT_FOUND",
          "INVALID_DOCUMENT_CATEGORY"
        ]
      }
    },
    "/shop/onboarding": {
      "get": {
        "operationId": "getOnboarding",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Profil tamamlama durumunu getir",
        "description": "Profilin eksikleri ve her birinin neyi beklettiği.\n\n**Erişim:** usta anahtarı · izin `read`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "checklist": {
                      "description": "Profil tamamlama listesi: her madde neyi beklettiğini söyler (iş almak, bir kategori, hakediş)."
                    },
                    "onboarding": {}
                  },
                  "required": [
                    "checklist",
                    "onboarding"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "read"
      }
    },
    "/shop/onboarding/accept-contract": {
      "post": {
        "operationId": "acceptUstaContract",
        "tags": [
          "Usta — Dükkân"
        ],
        "summary": "Usta sözleşmesini onayla",
        "description": "Hizmet veren sözleşmesinin onayını kaydeder.\n\n**Erişim:** usta anahtarı · izin `write`",
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shop": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "is_active": {
                          "description": "Çağrı merkezi onayladıysa `true`; yalnızca onaylı ustalar iş alır.",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "is_active"
                      ],
                      "additionalProperties": {}
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "shop",
                    "message"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_ROLE_REQUIRED` — Bu işlem anahtarın rolüyle yapılamaz.\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_ROLE_REQUIRED": {
                    "value": {
                      "message": "Bu işlem anahtarın rolüyle yapılamaz.",
                      "code": "PARTNER_ROLE_REQUIRED"
                    }
                  },
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "usta",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "NOT_FOUND"
        ]
      }
    },
    "/tickets": {
      "get": {
        "operationId": "listTickets",
        "tags": [
          "Destek"
        ],
        "summary": "Destek taleplerini listele",
        "description": "Hesabın destek talepleri.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "service_request_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tickets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "tickets"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      },
      "post": {
        "operationId": "createTicket",
        "tags": [
          "Destek"
        ],
        "summary": "Destek talebi aç",
        "description": "Ekibe bir talep açar. İptal istemek için `category: cancel_request` ve `service_request_id`.\n\n**Erişim:** her iki rol · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "category": {
                    "description": "`cancel_request`: rezervasyonun iptalini ister; ekip aynı iptal kurallarıyla sonuçlandırır.",
                    "type": "string",
                    "enum": [
                      "dispute",
                      "refund",
                      "quality",
                      "billing",
                      "cancel_request",
                      "general"
                    ]
                  },
                  "service_request_id": {
                    "type": "string"
                  },
                  "photos": {
                    "description": "`POST /uploads/photo` ile yüklenmiş dosya adresleri (en çok 5). Bu sunucunun üretmediği adresler sessizce düşürülür.",
                    "anyOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      {
                        "type": "string"
                      }
                    ]
                  }
                },
                "required": [
                  "subject",
                  "description"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ticket": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "ticket"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "ticket": {
                    "id": "01J00000000000000000000000",
                    "ticket_number": "TICK-00000000-0000",
                    "customer_id": "cus_01J00000000000000000000000",
                    "usta_id": null,
                    "order_id": null,
                    "service_request_id": "01J00000000000000000000000",
                    "escrow_id": null,
                    "extra_work_id": null,
                    "verdict": null,
                    "category": "cancel_request",
                    "status": "open",
                    "priority": "medium",
                    "subject": "Randevu",
                    "description": "Saati değiştirmek istiyorum.",
                    "resolution": null,
                    "assigned_to": null,
                    "sla_due_at": "2026-10-01T09:00:00.000Z",
                    "resolved_at": null,
                    "metadata": null,
                    "created_at": "2026-10-01T09:00:00.000Z",
                    "updated_at": "2026-10-01T09:00:00.000Z",
                    "deleted_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `INVALID_CATEGORY` — Destek kategorisi geçersiz.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "INVALID_CATEGORY": {
                    "value": {
                      "message": "Destek kategorisi geçersiz.",
                      "code": "INVALID_CATEGORY"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "INVALID_CATEGORY"
        ]
      }
    },
    "/tickets/{id}": {
      "get": {
        "operationId": "getTicket",
        "tags": [
          "Destek"
        ],
        "summary": "Destek talebini getir",
        "description": "Tek destek talebi.\n\n**Erişim:** her iki rol · izin `read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Kaydın kimliği.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ticket": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "ticket"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kayıt bulunamadı.\n\n- `NOT_FOUND` — Kayıt bulunamadı ya da size ait değil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "NOT_FOUND": {
                    "value": {
                      "message": "Kayıt bulunamadı ya da size ait değil.",
                      "code": "NOT_FOUND"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "read"
      }
    },
    "/uploads/photo": {
      "post": {
        "operationId": "uploadPhoto",
        "tags": [
          "Hesap"
        ],
        "summary": "Fotoğraf yükle",
        "description": "Base64 bir fotoğrafı yükler ve adresini döner. Rezervasyon fotoğrafı, soru cevabı, sohbet görseli ve iş tamamlama kanıtı yalnızca bu uçtan dönen adresleri kabul eder. En çok 8 MB; saatlik yükleme sınırı vardır.\n\n**Erişim:** her iki rol · izin `write`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "description": "Base64 dosya içeriği (`data:…;base64,` öneki olabilir), en çok 8 MB.",
                    "type": "string",
                    "minLength": 1
                  },
                  "file_name": {
                    "type": "string"
                  },
                  "mime_type": {
                    "description": "Varsayılan `image/jpeg`.",
                    "type": "string",
                    "enum": [
                      "image/jpeg",
                      "image/png",
                      "image/heic",
                      "image/webp"
                    ]
                  }
                },
                "required": [
                  "content"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Başarılı.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "file": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "description": "Rezervasyon, soru cevabı, sohbet ve tamamlama fotoğraflarında kullanılacak adres.",
                          "type": "string"
                        },
                        "file_name": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mime_type": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "url",
                        "file_name",
                        "mime_type"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "file"
                  ],
                  "additionalProperties": {}
                },
                "example": {
                  "file": {
                    "url": "https://api.example.com/static/shared/private-1790000000000-ug-cus_01J00000000000000000000000-1790000000000.png",
                    "file_name": null,
                    "mime_type": "image/png"
                  }
                }
              }
            }
          },
          "400": {
            "description": "İstek geçersiz.\n\n- `VALIDATION_ERROR` — İstek doğrulanamadı; ayrıntı `issues` alanında.\n- `UNSUPPORTED_MIME` — Dosya türü desteklenmiyor.\n- `FILE_TOO_LARGE` — Dosya en çok 8 MB olabilir.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "VALIDATION_ERROR": {
                    "value": {
                      "message": "İstek doğrulanamadı; ayrıntı `issues` alanında.",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "UNSUPPORTED_MIME": {
                    "value": {
                      "message": "Dosya türü desteklenmiyor.",
                      "code": "UNSUPPORTED_MIME"
                    }
                  },
                  "FILE_TOO_LARGE": {
                    "value": {
                      "message": "Dosya en çok 8 MB olabilir.",
                      "code": "FILE_TOO_LARGE"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Anahtar eksik, geçersiz, iptal edilmiş ya da süresi dolmuş.\n\n- `PARTNER_KEY_INVALID` — API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_KEY_INVALID": {
                    "value": {
                      "message": "API anahtarı geçersiz, iptal edilmiş ya da süresi dolmuş.",
                      "code": "PARTNER_KEY_INVALID"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Anahtarın rolü ya da izni bu işleme yetmiyor.\n\n- `PARTNER_SCOPE_REQUIRED` — Anahtarın bu işlem için izni yok.\n- `PARTNER_ROLE_UNAVAILABLE` — Anahtarın rolü bu hesapta artık yok.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "PARTNER_SCOPE_REQUIRED": {
                    "value": {
                      "message": "Anahtarın bu işlem için izni yok.",
                      "code": "PARTNER_SCOPE_REQUIRED"
                    }
                  },
                  "PARTNER_ROLE_UNAVAILABLE": {
                    "value": {
                      "message": "Anahtarın rolü bu hesapta artık yok.",
                      "code": "PARTNER_ROLE_UNAVAILABLE"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Hız sınırı aşıldı.\n\n- `RATE_LIMITED` — İstek kotası doldu; `Retry-After` kadar bekleyin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "RATE_LIMITED": {
                    "value": {
                      "message": "İstek kotası doldu; `Retry-After` kadar bekleyin.",
                      "code": "RATE_LIMITED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen hata.\n\n- `INTERNAL_ERROR` — Beklenmeyen bir hata oluştu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "INTERNAL_ERROR": {
                    "value": {
                      "message": "Beklenmeyen bir hata oluştu.",
                      "code": "INTERNAL_ERROR"
                    }
                  }
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": "write",
        "x-ug-error-codes": [
          "UNSUPPORTED_MIME",
          "FILE_TOO_LARGE"
        ]
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "tags": [
          "Meta"
        ],
        "summary": "API tanımını getir",
        "description": "Bu belgenin kendisi (OpenAPI 3.1). `lang=tr|en` açıklamaların dilini seçer. Anahtar gerekmez.\n\n**Erişim:** herkese açık, anahtar gerekmez.",
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Açıklama dili.",
            "schema": {
              "type": "string",
              "enum": [
                "tr",
                "en"
              ],
              "default": "tr"
            }
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI belgesi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-ug-role": "any",
        "x-ug-scope": null
      }
    }
  },
  "components": {
    "securitySchemes": {
      "PartnerKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "ugp_<64 hex>",
        "description": "Operasyon ekibinin panelden ürettiği partner anahtarı: `Authorization: Bearer ugp_…`."
      }
    },
    "schemas": {
      "ErrorResponse": {
        "description": "Başarısız her yanıtın gövdesi.",
        "type": "object",
        "properties": {
          "message": {
            "description": "İnsan için açıklama. Mağaza uçlarının mesajları Türkçe; partner katmanının kendi mesajları `Accept-Language: en` ile İngilizce.",
            "type": "string"
          },
          "code": {
            "description": "Kararlı, makinenin okuyacağı hata kodu. Dallanmayı buna göre yapın, mesaja göre değil.",
            "type": "string"
          },
          "issues": {
            "description": "Yalnızca VALIDATION_ERROR: hangi alan neden reddedildi.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                }
              },
              "required": [
                "path",
                "message",
                "code"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "message",
          "code"
        ],
        "additionalProperties": {}
      },
      "ErrorCode": {
        "type": "string",
        "description": "Bu API'nin döndürebileceği bütün hata kodları.",
        "enum": [
          "ADDRESS_REQUIRED",
          "ALREADY_TAKEN",
          "AMOUNT_NOT_LOWER",
          "AMOUNT_NOT_SET",
          "APPOINTMENT_REQUIRED",
          "AREA_NOT_COVERED",
          "AUTH_METHOD_DISABLED",
          "BAD_REQUEST",
          "BANK_TRANSFER_UNCONFIGURED",
          "BOOKING_NOT_PAID",
          "CANCEL_NOT_ALLOWED",
          "CARD_INVALID",
          "CATEGORY_DOCUMENTS_REQUIRED",
          "CATEGORY_NOT_COVERED",
          "CITY_NOT_COVERED",
          "CODE_EXPIRED",
          "CODE_INVALID",
          "CONFLICT",
          "CUSTOMER_METADATA_NOT_WRITABLE",
          "DATE_AND_SLOT",
          "DISPUTE_ALREADY_CONFIRMED",
          "DISPUTE_ALREADY_DISPUTED",
          "DISPUTE_NOT_HELD",
          "DISPUTE_REFUND_PENDING",
          "DISPUTE_STATEMENT_INVALID",
          "DISPUTE_TOO_EARLY",
          "DUPLICATE",
          "EMAIL_ALREADY_IN_USE",
          "EMAIL_CODE_COOLDOWN",
          "EMAIL_SEND_FAILED",
          "EMPTY_CART",
          "EMPTY_ITEMS",
          "ESCROW_DISPUTED",
          "ESCROW_EXISTS",
          "ESCROW_NOT_PAYABLE",
          "ESCROW_NOT_REFUNDABLE",
          "ESCROW_RELEASE_REQUIRES_REQUEST_CONFIRMATION",
          "EXTRA_WORK_PENDING",
          "FILE_TOO_LARGE",
          "FIXED_PRICE_PATH",
          "FORBIDDEN",
          "GROUP_NOT_ALLOWED",
          "GROUP_PAYMENT_CARRIER_ONLY",
          "GUEST_LIMIT",
          "HANDOFF_INVALID",
          "HOSTED_PAYMENT_UNAVAILABLE",
          "IBAN_HOLDER_MISMATCH",
          "IBAN_HOLDER_REQUIRED",
          "INTERNAL_ERROR",
          "INVALID_BIRTH_DATE",
          "INVALID_BUSINESS_PROFILE",
          "INVALID_CATEGORY",
          "INVALID_COMPLETION",
          "INVALID_COORDINATES",
          "INVALID_DATA",
          "INVALID_DATE",
          "INVALID_DOCUMENT_CATEGORY",
          "INVALID_DOC_TYPE",
          "INVALID_EMAIL",
          "INVALID_IBAN",
          "INVALID_JOB_STATUS",
          "INVALID_LINE_ITEMS",
          "INVALID_PHONE",
          "INVALID_REASON_CODE",
          "INVALID_SERVICE_ANSWER",
          "INVALID_SERVICE_ITEM",
          "INVALID_STATEMENT",
          "INVALID_STATUS",
          "INVALID_TC",
          "IN_PROGRESS",
          "JOB_ALREADY_CONFIRMED",
          "LEGAL_VERSION_CHANGED",
          "LOCATION_NOT_FOUND",
          "LOCATION_REQUIRED",
          "METHOD_NOT_ALLOWED",
          "MISSING_FIELDS",
          "MISSING_PERMISSION",
          "NAME_CHANGE_NOT_ALLOWED",
          "NOTHING_TO_UPDATE",
          "NOT_ALLOWED",
          "NOT_ASSIGNED",
          "NOT_AVAILABLE_AT_SLOT",
          "NOT_FOUND",
          "NOT_LIVE",
          "NOT_YOUR_JOB",
          "NOT_YOUR_REQUEST",
          "NO_PENDING_EMAIL",
          "NO_PENDING_RESCHEDULE",
          "NO_REGION",
          "NO_USTA_ASSIGNED",
          "OUTSIDE_SERVICE_AREA",
          "OWN_REQUEST",
          "PARTNER_KEY_INVALID",
          "PARTNER_ROLE_REQUIRED",
          "PARTNER_ROLE_UNAVAILABLE",
          "PARTNER_SCOPE_REQUIRED",
          "PAYLOAD_TOO_LARGE",
          "PAYMENT_AUTHORIZATION_ERROR",
          "PAYMENT_DECLINED",
          "PAYMENT_FAILED",
          "PAYMENT_GATEWAY_UNCONFIGURED",
          "PAYMENT_GATEWAY_UNREACHABLE",
          "PAYOUT_DETAILS_REQUIRED",
          "PENDING_ADMIN_APPROVAL",
          "PHONE_CHANGE_NOT_ALLOWED",
          "PHOTOS_LOCKED",
          "PRICE_OUT_OF_RANGE",
          "PRODUCT_NOT_FOUND",
          "QUOTE_CREATE_FAILED",
          "RATE_LIMITED",
          "REASON_TOO_SHORT",
          "REFUND_ALREADY_REQUESTED",
          "REFUND_AMOUNT_INVALID",
          "REFUND_BANK_REJECTED",
          "REFUND_BANK_UNREACHABLE",
          "REFUND_BANK_UNSUPPORTED",
          "REFUND_GATEWAY_UNAVAILABLE",
          "REFUND_GATEWAY_UNCONFIGURED",
          "REFUND_IN_PROGRESS",
          "REFUND_NO_PENDING_REQUEST",
          "REFUND_REASON_REQUIRED",
          "REFUND_REFERENCE_REQUIRED",
          "REFUND_REQUEST_PENDING",
          "REQUEST_NOT_FOUND",
          "REVERSE_GEOCODE_UNAVAILABLE",
          "REVERSE_GEOCODE_UNCONFIGURED",
          "SERVICE_AREA_NOT_COVERED",
          "SERVICE_CATEGORIES_REQUIRED",
          "SERVICE_UNAVAILABLE",
          "SESSION_EXPIRED",
          "SESSION_REVOKED",
          "SHOP_NOT_FOUND",
          "SLOT_CONFLICT",
          "STORE_METADATA_NOT_WRITABLE",
          "TOO_MANY_ATTEMPTS",
          "TOO_MANY_PAYMENT_ATTEMPTS",
          "TOO_MANY_REQUESTS",
          "UNAUTHORIZED",
          "UNEXPECTED_STATE",
          "UNPROCESSABLE",
          "UNSUPPORTED_FILE_URL",
          "UNSUPPORTED_MIME",
          "UPSTREAM_ERROR",
          "USTA_NOT_ACTIVE",
          "USTA_NOT_APPROVED",
          "USTA_PROFILE_REQUIRED",
          "USTA_ROLE_REQUIRED",
          "VALIDATION_ERROR",
          "VISIT_CODE_INVALID",
          "VISIT_CODE_NOT_ISSUED",
          "VISIT_CODE_REQUIRED",
          "WELCOME_PACKAGE_NOT_EARNED"
        ]
      }
    }
  }
}
