{
  "openapi": "3.1.0",
  "info": {
    "title": "PTF reality – Veřejné API",
    "version": "1.0.0",
    "summary": "Veřejné REST API realitní kanceláře PTF reality. Slouží pro AI agenty, integrace, partnery a mobilní aplikace.",
    "description": "REST API pro vyhledávání nemovitostí, čtení blogu, profilů makléřů, kanceláří, recenzí a odeslání kontaktního dotazu (lead).\n\n**Multi-tenant**: Všechny endpointy vyžadují HTTP hlavičku `X-Tenant-Slug` (typicky `ptf-reality`).\n\n**Jazyk**: Czech (cs-CZ).\n\n**Autorizace**: Veřejné endpointy jsou bez autorizace, pouze hlavička `X-Tenant-Slug` je povinná. Admin endpointy (`/api/admin/*`) zde nejsou dokumentovány.",
    "contact": {
      "name": "PTF reality s.r.o.",
      "email": "info@ptf.cz",
      "url": "https://ptf.cz/kontakt"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://ptf.cz/obchodni-podminky"
    },
    "termsOfService": "https://ptf.cz/obchodni-podminky"
  },
  "servers": [
    {
      "url": "https://api.ptf.cz",
      "description": "Produkční API"
    }
  ],
  "tags": [
    { "name": "Properties", "description": "Nemovitosti k prodeji a pronájmu" },
    { "name": "Blog", "description": "Realitní blog a články" },
    { "name": "Team", "description": "Realitní makléři a tým" },
    { "name": "Offices", "description": "Pobočky a kanceláře" },
    { "name": "Testimonials", "description": "Recenze klientů" },
    { "name": "Settings", "description": "Veřejná nastavení tenanta" },
    { "name": "Leads", "description": "Odeslání kontaktního dotazu" }
  ],
  "paths": {
    "/api/properties": {
      "get": {
        "tags": ["Properties"],
        "summary": "Seznam nemovitostí",
        "description": "Vrátí stránkovaný seznam nemovitostí s podporou filtrování. Hlavní endpoint pro AI agenty hledající byty/domy.",
        "operationId": "listProperties",
        "parameters": [
          { "$ref": "#/components/parameters/TenantSlug" },
          { "name": "offer_type", "in": "query", "schema": { "type": "string", "enum": ["prodej", "pronajem"] }, "description": "Typ nabídky: prodej nebo pronájem" },
          { "name": "property_type", "in": "query", "schema": { "type": "string", "enum": ["byt", "dum", "pozemek", "komercni", "ostatni"] }, "description": "Typ nemovitosti" },
          { "name": "property_subtype", "in": "query", "schema": { "type": "string" }, "description": "Podtyp (např. rodinný dům, vila)" },
          { "name": "city", "in": "query", "schema": { "type": "string" }, "description": "Město (např. Plzeň, Praha)" },
          { "name": "district", "in": "query", "schema": { "type": "string" }, "description": "Městská část / okres" },
          { "name": "disposition", "in": "query", "schema": { "type": "string" }, "description": "Dispozice (1+kk, 2+1, 3+kk, …). Lze zadat více oddělených čárkou." },
          { "name": "price_min", "in": "query", "schema": { "type": "integer", "minimum": 0 }, "description": "Minimální cena v Kč" },
          { "name": "price_max", "in": "query", "schema": { "type": "integer", "minimum": 0 }, "description": "Maximální cena v Kč" },
          { "name": "area_min", "in": "query", "schema": { "type": "integer", "minimum": 0 }, "description": "Minimální užitná plocha v m²" },
          { "name": "area_max", "in": "query", "schema": { "type": "integer", "minimum": 0 }, "description": "Maximální užitná plocha v m²" },
          { "name": "is_featured", "in": "query", "schema": { "type": "boolean" }, "description": "Pouze doporučené (TOP) nabídky" },
          { "name": "agent_id", "in": "query", "schema": { "type": "string", "format": "uuid" }, "description": "Filtr na konkrétního makléře" },
          { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Fulltextové vyhledávání v titulku a popisu" },
          { "name": "page", "in": "query", "schema": { "type": "integer", "minimum": 1, "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 12 } }
        ],
        "responses": {
          "200": {
            "description": "Stránkovaný seznam nemovitostí",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Property" } },
                    "pagination": { "$ref": "#/components/schemas/Pagination" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/properties/filters": {
      "get": {
        "tags": ["Properties"],
        "summary": "Dostupné filtry",
        "description": "Vrátí dostupné hodnoty pro dropdown filtry (města, dispozice, typy, cenové rozpětí). Užitečné pro AI agenty, kteří staví UI nebo validují vstupy.",
        "operationId": "getPropertyFilters",
        "parameters": [
          { "$ref": "#/components/parameters/TenantSlug" },
          { "name": "offer_type", "in": "query", "schema": { "type": "string", "enum": ["prodej", "pronajem"] } },
          { "name": "property_type", "in": "query", "schema": { "type": "string" } },
          { "name": "city", "in": "query", "schema": { "type": "string" } },
          { "name": "district", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Dostupné filtry",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AvailableFilters" } } }
          }
        }
      }
    },
    "/api/properties/featured": {
      "get": {
        "tags": ["Properties"],
        "summary": "Doporučené nemovitosti (TOP)",
        "operationId": "listFeaturedProperties",
        "parameters": [
          { "$ref": "#/components/parameters/TenantSlug" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 6 } }
        ],
        "responses": {
          "200": {
            "description": "Seznam doporučených nabídek",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/PropertySummary" } } } } } }
          }
        }
      }
    },
    "/api/properties/{slug}": {
      "get": {
        "tags": ["Properties"],
        "summary": "Detail nemovitosti",
        "operationId": "getPropertyBySlug",
        "parameters": [
          { "$ref": "#/components/parameters/TenantSlug" },
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" }, "description": "URL slug nemovitosti" }
        ],
        "responses": {
          "200": { "description": "Detail nemovitosti", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Property" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/api/blog": {
      "get": {
        "tags": ["Blog"],
        "summary": "Seznam blogových článků",
        "operationId": "listBlogPosts",
        "parameters": [
          { "$ref": "#/components/parameters/TenantSlug" },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 12 } },
          { "name": "category", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Seznam článků",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/BlogPost" } }, "pagination": { "$ref": "#/components/schemas/Pagination" } } } } }
          }
        }
      }
    },
    "/api/blog/{slug}": {
      "get": {
        "tags": ["Blog"],
        "summary": "Detail blogového článku",
        "operationId": "getBlogPostBySlug",
        "parameters": [
          { "$ref": "#/components/parameters/TenantSlug" },
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Detail článku", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlogPost" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/api/team": {
      "get": {
        "tags": ["Team"],
        "summary": "Seznam makléřů",
        "operationId": "listTeamMembers",
        "parameters": [{ "$ref": "#/components/parameters/TenantSlug" }],
        "responses": {
          "200": { "description": "Seznam makléřů", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TeamMember" } } } } }
        }
      }
    },
    "/api/team/{slug}": {
      "get": {
        "tags": ["Team"],
        "summary": "Detail makléře",
        "operationId": "getTeamMemberBySlug",
        "parameters": [
          { "$ref": "#/components/parameters/TenantSlug" },
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Detail makléře", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeamMember" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/api/offices": {
      "get": {
        "tags": ["Offices"],
        "summary": "Seznam poboček",
        "operationId": "listOffices",
        "parameters": [{ "$ref": "#/components/parameters/TenantSlug" }],
        "responses": {
          "200": { "description": "Seznam poboček", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Office" } } } } }
        }
      }
    },
    "/api/testimonials": {
      "get": {
        "tags": ["Testimonials"],
        "summary": "Recenze klientů",
        "operationId": "listTestimonials",
        "parameters": [{ "$ref": "#/components/parameters/TenantSlug" }],
        "responses": {
          "200": { "description": "Seznam recenzí", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Testimonial" } } } } }
        }
      }
    },
    "/api/settings": {
      "get": {
        "tags": ["Settings"],
        "summary": "Veřejná nastavení tenanta",
        "description": "Vrátí veřejné info: název firmy, kontakty, sociální sítě, otevírací dobu.",
        "operationId": "getPublicSettings",
        "parameters": [{ "$ref": "#/components/parameters/TenantSlug" }],
        "responses": {
          "200": { "description": "Nastavení", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublicSettings" } } } }
        }
      }
    },
    "/api/leads": {
      "post": {
        "tags": ["Leads"],
        "summary": "Odeslat kontaktní dotaz / lead",
        "description": "Vytvoří nový kontakt/dotaz. Slouží AI agentům k předání zájmu uživatele (poptávka po nemovitosti, žádost o ocenění, kontakt s makléřem).",
        "operationId": "createLead",
        "parameters": [{ "$ref": "#/components/parameters/TenantSlug" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/LeadInput" }
            }
          }
        },
        "responses": {
          "201": { "description": "Lead úspěšně vytvořen", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" } } } } } },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "TenantSlug": {
        "name": "X-Tenant-Slug",
        "in": "header",
        "required": true,
        "schema": { "type": "string", "default": "ptf-reality" },
        "description": "Identifikátor tenanta (typicky `ptf-reality`)"
      }
    },
    "responses": {
      "NotFound": { "description": "Záznam nenalezen", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "BadRequest": { "description": "Neplatný požadavek", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    },
    "schemas": {
      "Pagination": {
        "type": "object",
        "properties": {
          "total": { "type": "integer" },
          "page": { "type": "integer" },
          "limit": { "type": "integer" },
          "totalPages": { "type": "integer" }
        }
      },
      "Error": {
        "type": "object",
        "properties": { "error": { "type": "string" } }
      },
      "PropertySummary": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "slug": { "type": "string" },
          "price": { "type": "number", "nullable": true },
          "priceUnit": { "type": "string", "nullable": true },
          "addressCity": { "type": "string" },
          "mainImageUrl": { "type": "string", "format": "uri", "nullable": true },
          "offerType": { "type": "string", "enum": ["prodej", "pronajem"] }
        }
      },
      "Property": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "slug": { "type": "string" },
          "property_type": { "type": "string", "enum": ["byt", "dum", "pozemek", "komercni", "ostatni"] },
          "offer_type": { "type": "string", "enum": ["prodej", "pronajem"] },
          "status": { "type": "string", "enum": ["aktivni", "rezervovano", "prodano", "neaktivni"] },
          "disposition": { "type": "string", "nullable": true },
          "price": { "type": "number", "nullable": true },
          "price_unit": { "type": "string", "nullable": true },
          "price_per_m2": { "type": "number", "nullable": true },
          "area_total": { "type": "number", "nullable": true },
          "area_usable": { "type": "number", "nullable": true },
          "area_land": { "type": "number", "nullable": true },
          "address_street": { "type": "string", "nullable": true },
          "address_city": { "type": "string" },
          "address_district": { "type": "string", "nullable": true },
          "address_zip": { "type": "string", "nullable": true },
          "address_region": { "type": "string", "nullable": true },
          "gps_lat": { "type": "number", "nullable": true },
          "gps_lng": { "type": "number", "nullable": true },
          "description_short": { "type": "string", "nullable": true },
          "description": { "type": "string", "nullable": true },
          "energy_class": { "type": "string", "nullable": true },
          "year_built": { "type": "integer", "nullable": true },
          "is_featured": { "type": "boolean" },
          "is_offmarket": { "type": "boolean" },
          "video_url": { "type": "string", "format": "uri", "nullable": true },
          "virtual_tour_url": { "type": "string", "format": "uri", "nullable": true },
          "published_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" },
          "images": { "type": "array", "items": { "$ref": "#/components/schemas/PropertyImage" } },
          "agent": { "$ref": "#/components/schemas/TeamMember" }
        }
      },
      "PropertyImage": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "url": { "type": "string", "format": "uri" },
          "url_thumbnail": { "type": "string", "format": "uri", "nullable": true },
          "url_large": { "type": "string", "format": "uri", "nullable": true },
          "alt_text": { "type": "string", "nullable": true },
          "is_main": { "type": "boolean" },
          "sort_order": { "type": "integer" }
        }
      },
      "AvailableFilters": {
        "type": "object",
        "properties": {
          "offer_types": { "type": "array", "items": { "type": "string" } },
          "property_types": { "type": "array", "items": { "type": "string" } },
          "property_subtypes": { "type": "array", "items": { "type": "string" } },
          "cities": { "type": "array", "items": { "type": "string" } },
          "districts": { "type": "array", "items": { "type": "string" } },
          "regions": { "type": "array", "items": { "type": "string" } },
          "dispositions": { "type": "array", "items": { "type": "string" } },
          "price": { "type": "object", "properties": { "min": { "type": "number" }, "max": { "type": "number" } } },
          "area": { "type": "object", "properties": { "min": { "type": "number" }, "max": { "type": "number" } } }
        }
      },
      "BlogPost": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "slug": { "type": "string" },
          "excerpt": { "type": "string", "nullable": true },
          "content": { "type": "string" },
          "featuredImageUrl": { "type": "string", "format": "uri", "nullable": true },
          "tags": { "type": "array", "items": { "type": "string" } },
          "status": { "type": "string", "enum": ["draft", "published"] },
          "publishedAt": { "type": "string", "format": "date-time", "nullable": true },
          "viewsCount": { "type": "integer" },
          "createdAt": { "type": "string", "format": "date-time" },
          "updatedAt": { "type": "string", "format": "date-time" },
          "author": { "$ref": "#/components/schemas/TeamMember" }
        }
      },
      "TeamMember": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "firstName": { "type": "string" },
          "lastName": { "type": "string" },
          "slug": { "type": "string" },
          "title": { "type": "string", "nullable": true },
          "professionalTitle": { "type": "string", "nullable": true },
          "bio": { "type": "string", "nullable": true },
          "shortBio": { "type": "string", "nullable": true },
          "phone": { "type": "string", "nullable": true },
          "email": { "type": "string", "format": "email", "nullable": true },
          "photoUrl": { "type": "string", "format": "uri", "nullable": true },
          "yearsExperience": { "type": "integer", "nullable": true },
          "areasServed": { "type": "array", "items": { "type": "string" } },
          "specializations": { "type": "array", "items": { "type": "string" } },
          "languages": { "type": "array", "items": { "type": "string" } }
        }
      },
      "Office": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "address": { "type": "string" },
          "city": { "type": "string" },
          "zip": { "type": "string" },
          "phone": { "type": "string", "nullable": true },
          "email": { "type": "string", "nullable": true },
          "gps_lat": { "type": "number", "nullable": true },
          "gps_lng": { "type": "number", "nullable": true },
          "opening_hours": { "type": "string", "nullable": true }
        }
      },
      "Testimonial": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "author_name": { "type": "string" },
          "author_role": { "type": "string", "nullable": true },
          "rating": { "type": "integer", "minimum": 1, "maximum": 5 },
          "content": { "type": "string" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "PublicSettings": {
        "type": "object",
        "properties": {
          "company_name": { "type": "string" },
          "phone": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "address": { "type": "string" },
          "social": {
            "type": "object",
            "properties": {
              "facebook": { "type": "string", "format": "uri" },
              "instagram": { "type": "string", "format": "uri" },
              "linkedin": { "type": "string", "format": "uri" }
            }
          }
        }
      },
      "LeadInput": {
        "type": "object",
        "required": ["name", "email", "message"],
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string", "nullable": true },
          "message": { "type": "string", "minLength": 1 },
          "source": { "type": "string", "description": "Zdroj leadu (např. ai-agent, chatbot, kontaktni-formular)" },
          "property_id": { "type": "string", "format": "uuid", "nullable": true, "description": "Pokud se dotaz týká konkrétní nemovitosti" },
          "agent_id": { "type": "string", "format": "uuid", "nullable": true, "description": "Pokud se dotaz týká konkrétního makléře" },
          "lead_type": { "type": "string", "enum": ["valuation", "purchase", "rental", "consultation", "other"] },
          "consent_gdpr": { "type": "boolean", "description": "Souhlas se zpracováním osobních údajů" }
        }
      }
    }
  }
}
