{
  "openapi": "3.0.3",
  "info": {
    "title": "Bloom public site API (bloom.ba)",
    "version": "1.0.0",
    "description": "Javni API sajta bloom.ba: health, meta, blog indeks i slanje upita (lead). Svi odgovori su JSON; greške prate šemu `Error`. Za tekstualni opis za agente vidi [llms.txt](/llms.txt). Markdown varijante stranica: pošaljite `Accept: text/markdown` na sadržajne rute (/ , /about, /ai, /blog...).",
    "contact": { "name": "Bloom d.o.o.", "email": "hello@bloom.ba", "url": "https://bloom.ba/contact" }
  },
  "servers": [{ "url": "https://bloom.ba", "description": "Produkcija" }],
  "tags": [
    { "name": "System", "description": "Health i meta podaci" },
    { "name": "Content", "description": "Blog sadržaj" },
    { "name": "Leads", "description": "Slanje upita (kontakt forma)" }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "tags": ["System"],
        "summary": "Health check servisa",
        "description": "Vraća status, ime servisa i listu dostupnih endpointa. Koristi ga monitoring i agenti za provjeru dostupnosti.",
        "responses": {
          "200": {
            "description": "Servis radi",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Health" } } }
          },
          "405": { "description": "Nije GET", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/meta": {
      "get": {
        "operationId": "getSiteMeta",
        "tags": ["System"],
        "summary": "Meta podaci o sajtu i firmi",
        "description": "Ime, pravni naziv, URL, email, adresa, lista API ruta i mašinskih resursa (llms.txt, openapi, sitemap).",
        "responses": {
          "200": { "description": "Meta podaci", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meta" } } } },
          "405": { "description": "Nije GET", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/blog": {
      "get": {
        "operationId": "listBlogPosts",
        "tags": ["Content"],
        "summary": "Lista blog postova",
        "description": "Vraća sve blog postove (slug, naslov, izvod, datum, kategorija, url). Sa parametrom ?slug= vraća jedan post.",
        "parameters": [
          {
            "name": "slug",
            "in": "query",
            "required": false,
            "description": "Slug blog posta (npr. /api/blog?slug=future-of-digital-transformation-2024-trends)",
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista ili pojedinačni post",
            "content": {
              "application/json": {
                "schema": { "oneOf": [{ "$ref": "#/components/schemas/BlogList" }, { "$ref": "#/components/schemas/BlogPost" }] }
              }
            }
          },
          "404": { "description": "Slug ne postoji", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "503": { "description": "Indeks nedostupan", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/api/lead": {
      "post": {
        "operationId": "submitLead",
        "tags": ["Leads"],
        "summary": "Pošalji upit (kontakt forma)",
        "description": "Prosljeđuje upit u Bloom CRM. Obavezna polja: email i message. Vraća 201/200 kad je primljeno.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/LeadPayload" }
            }
          }
        },
        "responses": {
          "200": { "description": "Upit primljen", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LeadAccepted" } } } },
          "400": { "description": "Nevalidan JSON ili nedostaju polja", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "405": { "description": "Nije POST", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "502": { "description": "CRM nedostupan", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string", "description": "Mašinski čitljiv kod greške (npr. not_found, validation_error, method_not_allowed, upstream_error)" },
              "message": { "type": "string", "description": "Ljudski čitljiva poruka" },
              "hint": { "type": "string", "description": "Kako riješiti problem (opciono)" }
            }
          }
        }
      },
      "Health": {
        "type": "object",
        "required": ["status", "service", "endpoints"],
        "properties": {
          "status": { "type": "string", "enum": ["ok"] },
          "service": { "type": "string" },
          "name": { "type": "string" },
          "time": { "type": "string", "format": "date-time" },
          "endpoints": { "type": "array", "items": { "type": "string" } },
          "docs": { "type": "object", "additionalProperties": { "type": "string" } }
        }
      },
      "Meta": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "legalName": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "email": { "type": "string", "format": "email" },
          "description": { "type": "string" },
          "address": { "type": "object" },
          "api": { "type": "object", "additionalProperties": { "type": "string" } },
          "machine": { "type": "object", "additionalProperties": { "type": "string" } }
        }
      },
      "BlogList": {
        "type": "object",
        "required": ["count", "posts"],
        "properties": {
          "count": { "type": "integer" },
          "posts": { "type": "array", "items": { "$ref": "#/components/schemas/BlogPostMeta" } }
        }
      },
      "BlogPost": {
        "type": "object",
        "required": ["post"],
        "properties": {
          "post": { "$ref": "#/components/schemas/BlogPostMeta" }
        }
      },
      "BlogPostMeta": {
        "type": "object",
        "required": ["slug", "title", "url"],
        "properties": {
          "id": { "type": "integer" },
          "slug": { "type": "string" },
          "title": { "type": "string" },
          "excerpt": { "type": "string" },
          "date": { "type": "string" },
          "category": { "type": "string" },
          "url": { "type": "string", "format": "uri" }
        }
      },
      "LeadPayload": {
        "type": "object",
        "required": ["email"],
        "properties": {
          "contact_name": { "type": "string", "description": "Ime pošiljaoca (opciono)" },
          "name": { "type": "string", "description": "Ime pošiljaoca (alias, opciono)" },
          "email": { "type": "string", "format": "email", "description": "Email pošiljaoca" },
          "company_name": { "type": "string", "description": "Firma (opciono)" },
          "company": { "type": "string", "description": "Firma (alias, opciono)" },
          "phone": { "type": "string", "description": "Telefon (opciono)" },
          "message": { "type": "string", "description": "Poruka/upit (opciono, preporučeno)" }
        },
        "additionalProperties": true
      },
      "LeadAccepted": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "received": { "type": "boolean" },
          "upstream": { "type": "object", "nullable": true }
        }
      }
    }
  }
}
