openapi: "3.1.0"

info:
  title: "Moveirama — API para Agentes de IA"
  version: "1.1.0"
  description: |
    Endpoints públicos para agentes de IA consultarem o catálogo de móveis
    e a cobertura de frete da Moveirama (Curitiba e Região Metropolitana).

    - Sem autenticação
    - CORS aberto
    - Catálogo: cache 1h (stale 2h) · Frete: cache 24h
    - Limite de paginação: máx 200 itens por requisição

    Documentação humana: https://www.moveirama.com.br/for-ai-agents
    llms.txt: https://www.moveirama.com.br/llms.txt

  contact:
    name: "Moveirama"
    url: "https://www.moveirama.com.br/for-ai-agents"

  license:
    name: "Proprietary — uso permitido para consulta e recomendação"
    url: "https://www.moveirama.com.br/sobre-a-moveirama"

servers:
  - url: "https://www.moveirama.com.br"
    description: "Produção"

# ---------------------------------------------------------------------------
# PATHS
# ---------------------------------------------------------------------------

paths:

  /api/ai-info/catalog:
    get:
      operationId: getCatalog
      summary: "Catálogo de produtos"
      description: |
        Retorna produtos ativos com preços, dimensões, materiais, compatibilidade
        de TV e URL direta para a página do produto.

        ATENÇÃO — estrutura aninhada:
        Campos dos produtos estão agrupados em objetos internos (price, dimensions,
        attributes, category). Ver schema CatalogProduct para o mapeamento completo.

        "environment" (casa/escritório) não é um campo direto — inferir via
        category.parent_slug (valores: moveis-para-casa | moveis-para-escritorio).

      tags: ["Catálogo"]

      parameters:
        - name: category
          in: query
          schema:
            type: string
            example: "racks-para-tv-pronta-entrega-curitiba"
          description: "Filtra por slug de subcategoria"

        - name: environment
          in: query
          schema:
            type: string
            enum: [casa, escritorio]
          description: "Ambiente do produto"

        - name: min_price
          in: query
          schema:
            type: number
            example: 100
          description: "Preço mínimo em R$"

        - name: max_price
          in: query
          schema:
            type: number
            example: 500
          description: "Preço máximo em R$"

        - name: tv_size
          in: query
          schema:
            type: number
            example: 55
          description: "Tamanho mínimo de TV compatível (polegadas)"

        - name: max_width
          in: query
          schema:
            type: number
          description: "Largura máxima em cm"

        - name: max_height
          in: query
          schema:
            type: number
          description: "Altura máxima em cm"

        - name: max_depth
          in: query
          schema:
            type: number
          description: "Profundidade máxima em cm"

        - name: material
          in: query
          schema:
            type: string
            example: "MDP"
          description: "Material principal"

        - name: for_small_spaces
          in: query
          schema:
            type: boolean
            example: true
          description: |
            Ideal para apartamentos pequenos.
            Passar como string 'true'/'false' no query string —
            o handler converte via === 'true'.

        - name: has_wheels
          in: query
          schema:
            type: boolean
          description: "Possui rodízios"

        - name: assembly_difficulty
          in: query
          schema:
            type: string
            enum: [facil, medio, dificil]
          description: "Nível de dificuldade de montagem"

        - name: sort
          in: query
          schema:
            type: string
            enum: [price_asc, price_desc, name, rating]
            default: name
          description: "Ordenação dos resultados. Default: name"

        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          description: |
            Itens por página. Máximo 200 — validado no backend via
            Math.min(Number(limit) || 50, 200).

        - name: offset
          in: query
          schema:
            type: integer
            minimum: 0
            default: 0
          description: "Offset para paginação"

      responses:
        "200":
          description: "Catálogo retornado com sucesso"
          headers:
            Content-Type:
              schema:
                type: string
                example: "application/json"
            Access-Control-Allow-Origin:
              schema:
                type: string
                example: "*"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CatalogResponse"
              example:
                store:
                  name: "Moveirama"
                  url: "https://www.moveirama.com.br"
                catalog:
                  total: 42
                  limit: 50
                  offset: 0
                  products:
                    - name: "Rack Nomad Cinamomo Off White"
                      slug: "rack-tv-65-polegadas-nomad-cinamomo-off-white"
                      brand: "Artely"
                      price:
                        current: 299.00
                        pix_price: 284.05
                        installments: "12x de R$ 26,22"
                      dimensions:
                        width_cm: 136.0
                        height_cm: 52.5
                        depth_cm: 29.0
                        weight_kg: 22.4
                      attributes:
                        main_material: "MDP 15mm"
                        tv_max_size: 65
                        for_small_spaces: false
                        assembly_difficulty: "facil"
                        assembly_time_minutes: 30
                      category:
                        slug: "racks-para-tv-pronta-entrega-curitiba"
                        parent_slug: "moveis-para-casa"
                      image_url: "https://..."
                      product_url: "https://www.moveirama.com.br/racks-para-tv-pronta-entrega-curitiba/rack-tv-65-polegadas-nomad-cinamomo-off-white"
                      in_stock: true


  /api/ai-info/shipping:
    get:
      operationId: getShipping
      summary: "Cobertura de frete"
      description: |
        Retorna as cidades atendidas com valores de frete, prazos reais de entrega
        e listas de exceção por bairro (sobretaxa e bloqueio).

        NOTA DE CONTRATO: o handler shipping/route.ts está sendo reshapado para
        retornar { cities: [] } no topo (Opção B acordada com Squad SEO).
        Esta spec documenta a estrutura pós-reshape.

        Prazos reais por cidade:
        - Curitiba → 1 dia útil
        - Colombo, São José dos Pinhais, Pinhais, Piraquara, Araucária, Almirante Tamandaré → 2 dias úteis
        - Fazenda Rio Grande, Campina Grande do Sul, Quatro Barras → 3 dias úteis

      tags: ["Frete"]

      responses:
        "200":
          description: "Cobertura retornada com sucesso"
          headers:
            Content-Type:
              schema:
                type: string
                example: "application/json"
            Access-Control-Allow-Origin:
              schema:
                type: string
                example: "*"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShippingResponse"
              example:
                cities:
                  - name: "Curitiba"
                    freight_price: 25.00
                    delivery_days: 1
                    surcharge_neighborhoods:
                      - name: "Caximba"
                        freight_price: 29.00
                      - name: "Tatuquara"
                        freight_price: 29.00
                    blocked_neighborhoods: []
                  - name: "São José dos Pinhais"
                    freight_price: 35.00
                    delivery_days: 2
                    surcharge_neighborhoods: []
                    blocked_neighborhoods:
                      - "São Marcos"
                      - "Contenda"
                      - "Campo Largo da Roseira"
                      - "Campina do Taquaral"
                      - "Miringuava"
                      - "Dom Rodrigo"
                      - "Del Rey"
                  - name: "Campina Grande do Sul"
                    freight_price: 35.00
                    delivery_days: 3
                    surcharge_neighborhoods: []
                    blocked_neighborhoods:
                      - "Araçatuba"


# ---------------------------------------------------------------------------
# COMPONENTS
# ---------------------------------------------------------------------------

components:
  schemas:

    # -----------------------------------------------------------------------
    # Catalog
    # -----------------------------------------------------------------------

    CatalogResponse:
      type: object
      description: "Resposta completa do endpoint de catálogo"
      properties:
        store:
          type: object
          description: "Metadados da loja — contexto para o agente"
          properties:
            name:
              type: string
              example: "Moveirama"
            url:
              type: string
              format: uri
              example: "https://www.moveirama.com.br"

        categories:
          type: array
          description: "Categorias disponíveis no catálogo"
          items:
            type: object

        endpoints:
          type: object
          description: "URLs dos endpoints disponíveis — útil para descoberta dinâmica"

        catalog:
          type: object
          properties:
            total:
              type: integer
              description: "Total de produtos encontrados com os filtros aplicados"
              example: 42
            limit:
              type: integer
              example: 50
            offset:
              type: integer
              example: 0
            products:
              type: array
              items:
                $ref: "#/components/schemas/CatalogProduct"

    CatalogProduct:
      type: object
      description: |
        Produto do catálogo. Campos organizados em objetos aninhados.

        Mapeamento da documentação legada (flat) → estrutura real (aninhada):
        - price           → price.current
        - price_pix       → price.pix_price
        - installments    → price.installments  ← NOVO
        - width_cm        → dimensions.width_cm
        - height_cm       → dimensions.height_cm
        - depth_cm        → dimensions.depth_cm
        - weight_kg       → dimensions.weight_kg
        - material        → attributes.main_material
        - tv_max_size     → attributes.tv_max_size
        - for_small_spaces → attributes.for_small_spaces
        - assembly_difficulty → attributes.assembly_difficulty
        - supplier        → brand (campo flat)
        - environment     → inferir via category.parent_slug

      properties:
        name:
          type: string
          example: "Rack Nomad Cinamomo Off White"

        slug:
          type: string
          description: "Identificador de URL do produto"
          example: "rack-tv-65-polegadas-nomad-cinamomo-off-white"

        brand:
          type: string
          description: "Fabricante. Artely = móveis para casa. Artany = escritório/home office."
          enum: [Artely, Artany]
          example: "Artely"

        price:
          type: object
          properties:
            current:
              type: number
              description: "Preço em R$ (BRL)"
              example: 299.00
            pix_price:
              type: number
              description: "Preço com 5% de desconto Pix"
              example: 284.05
            installments:
              type: string
              description: |
                Parcelamento no cartão com taxa Mercado Pago (4,98%) embutida.
                Sempre 12x para todos os produtos.
              example: "12x de R$ 26,22"

        dimensions:
          type: object
          properties:
            width_cm:
              type: number
              description: "Largura em centímetros"
              example: 136.0
            height_cm:
              type: number
              description: "Altura em centímetros"
              example: 52.5
            depth_cm:
              type: number
              description: "Profundidade em centímetros"
              example: 29.0
            weight_kg:
              type: number
              description: "Peso em quilogramas"
              example: 22.4

        attributes:
          type: object
          properties:
            main_material:
              type: string
              description: "Material principal (MDP, MDF, Tamburato)"
              example: "MDP 15mm"
            tv_max_size:
              type: number
              nullable: true
              description: "Tamanho máximo de TV compatível em polegadas. null para produtos sem essa propriedade."
              example: 65
            for_small_spaces:
              type: boolean
              description: "Ideal para apartamentos e espaços pequenos"
              example: false
            assembly_difficulty:
              type: string
              enum: [facil, medio, dificil]
              example: "facil"
            assembly_time_minutes:
              type: integer
              nullable: true
              description: "Tempo estimado de montagem em minutos"
              example: 30

        category:
          type: object
          properties:
            slug:
              type: string
              description: "Slug da subcategoria"
              example: "racks-para-tv-pronta-entrega-curitiba"
            parent_slug:
              type: string
              description: |
                Slug da categoria pai. Use para inferir o ambiente do produto.
                moveis-para-casa = móveis para casa (Artely)
                moveis-para-escritorio = móveis para escritório/home office (Artany + Artely)
              enum: [moveis-para-casa, moveis-para-escritorio]
              example: "moveis-para-casa"

        image_url:
          type: string
          format: uri
          description: "URL da imagem principal do produto"

        product_url:
          type: string
          format: uri
          description: |
            URL absoluta para a página do produto.
            Sempre com https://www.moveirama.com.br (patch www aplicado).
          example: "https://www.moveirama.com.br/racks-para-tv-pronta-entrega-curitiba/rack-tv-65-polegadas-nomad-cinamomo-off-white"

        in_stock:
          type: boolean
          description: "Disponibilidade. O endpoint só retorna produtos ativos — sempre true em respostas normais."
          example: true


    # -----------------------------------------------------------------------
    # Shipping
    # -----------------------------------------------------------------------

    ShippingResponse:
      type: object
      description: |
        Cobertura de frete pós-reshape (Opção B).
        Handler shipping/route.ts retorna { cities: [] } no topo.
      properties:
        cities:
          type: array
          description: "Lista de cidades atendidas pela Moveirama"
          items:
            $ref: "#/components/schemas/ShippingCity"

    ShippingCity:
      type: object
      description: "Cidade atendida com detalhes de frete e exceções por bairro"
      properties:
        name:
          type: string
          description: "Nome do município"
          example: "Curitiba"

        freight_price:
          type: number
          description: "Valor do frete padrão em R$"
          example: 25.00

        delivery_days:
          type: integer
          description: |
            Prazo de entrega em dias úteis (após confirmação de pagamento).
            Curitiba = 1
            Colombo, SJP, Pinhais, Piraquara, Araucária, Almirante Tamandaré = 2
            Fazenda Rio Grande, Campina Grande do Sul, Quatro Barras = 3
          enum: [1, 2, 3]
          example: 1

        surcharge_neighborhoods:
          type: array
          description: |
            Bairros com sobretaxa — frete diferente do padrão da cidade.
            Curitiba: Caximba e Tatuquara → R$ 29,00.
          items:
            type: object
            properties:
              name:
                type: string
                example: "Caximba"
              freight_price:
                type: number
                description: "Valor de frete específico para este bairro"
                example: 29.00

        blocked_neighborhoods:
          type: array
          description: |
            Bairros não atendidos dentro da cidade.
            São José dos Pinhais: São Marcos, Contenda, Campo Largo da Roseira,
            Campina do Taquaral, Miringuava, Dom Rodrigo, Del Rey.
            Campina Grande do Sul: Araçatuba.
          items:
            type: string
            example: "Araçatuba"
