{
    "openapi": "3.0.3",
    "info": {
        "title": "Viagilize API",
        "description": "API REST V1 do Viagilize: gestão de excursões, pacotes, clientes e reservas.\n\nAutenticação: header `Authorization: Bearer vgl_...`, com o token gerado em Configurações → API.\n\nLimite de uso: 700 requisições por minuto, por token. Ao exceder, a resposta é HTTP 429 com `Retry-After`. Toda resposta traz `X-RateLimit-Limit` e `X-RateLimit-Remaining`.",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://{tenant}.viagilize.com.br/api/v1",
            "variables": {
                "tenant": {
                    "default": "demo"
                }
            }
        }
    ],
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "Token de API prefixado com vgl_ (ex: Authorization: Bearer vgl_xxx)."
            }
        }
    },
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "paths": {
        "/excursoes": {
            "get": {
                "tags": [
                    "Excursões"
                ],
                "summary": "Listar excursões",
                "description": "Retorna uma lista paginada de excursões/pacotes com filtros.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Número da página",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens por página (max: 100)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "rascunho, publicada, cancelada, finalizada",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "tipo_excursao",
                        "in": "query",
                        "required": false,
                        "description": "excursao ou pacote_viagem",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "categoria_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por categoria",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por nome, cidade ou destino",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_inicio_de",
                        "in": "query",
                        "required": false,
                        "description": "Data de início mínima (Y-m-d)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_inicio_ate",
                        "in": "query",
                        "required": false,
                        "description": "Data de início máxima (Y-m-d)",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 45,
                                            "nome": "Gramado - Natal Luz 2025",
                                            "slug": "gramado-natal-luz-2025",
                                            "tipo_excursao": "excursao",
                                            "cidade": "Gramado",
                                            "estado": "RS",
                                            "pais": "Brasil",
                                            "local": "Gramado/RS",
                                            "data_inicio": "2025-12-20",
                                            "data_fim": "2025-12-24",
                                            "hora_inicio": "06:00",
                                            "hora_fim": "22:00",
                                            "status": "publicada",
                                            "vagas_maximas": 46,
                                            "imagem": "https://.../gramado.jpg",
                                            "categorias": [
                                                {
                                                    "id": 1,
                                                    "nome": "Adulto"
                                                }
                                            ],
                                            "embarques": [
                                                {
                                                    "id": 12,
                                                    "nome": "Terminal Tietê",
                                                    "cidade": "São Paulo",
                                                    "hora_embarque": "06:00"
                                                }
                                            ]
                                        }
                                    ],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 45,
                                        "last_page": 3
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Excursões"
                ],
                "summary": "Criar excursão ou pacote",
                "description": "Cria uma excursão (rodoviária) ou pacote de viagem. Pode receber arrays aninhados (transportes, embarques, precos) para criar tudo em uma única chamada, similar ao wizard do admin.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Excursão criada com sucesso.",
                                    "data": {
                                        "id": 123,
                                        "nome": "Nova Excursão",
                                        "slug": "nova-excursao-xyz123",
                                        "tipo_excursao": "excursao",
                                        "status": "rascunho",
                                        "data_inicio": "2026-05-10",
                                        "vagas_maximas": 46,
                                        "categorias": [
                                            {
                                                "id": 1,
                                                "nome": "Adulto"
                                            }
                                        ],
                                        "transportes": [
                                            {
                                                "id": 101,
                                                "veiculo_id": 5,
                                                "vagas_total": 46
                                            }
                                        ],
                                        "embarques": [
                                            {
                                                "id": 210,
                                                "nome": "Terminal Tietê",
                                                "hora_embarque": "06:00"
                                            }
                                        ],
                                        "precos": [
                                            {
                                                "id": 305,
                                                "categoria_id": 1,
                                                "valor": 1450
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome da excursão/pacote"
                                    },
                                    "slug": {
                                        "type": "string",
                                        "description": "Slug (gerado automaticamente se omitido)"
                                    },
                                    "tipo_excursao": {
                                        "type": "string",
                                        "description": "excursao (default) ou pacote_viagem"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição longa"
                                    },
                                    "imagem": {
                                        "type": "string",
                                        "description": "URL da imagem principal"
                                    },
                                    "galeria": {
                                        "type": "array",
                                        "description": "Array de URLs de imagens"
                                    },
                                    "pais": {
                                        "type": "string",
                                        "description": "País"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "Estado/UF"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "local": {
                                        "type": "string",
                                        "description": "Local/destino"
                                    },
                                    "data_inicio": {
                                        "type": "string",
                                        "description": "Data de início (Y-m-d)"
                                    },
                                    "data_fim": {
                                        "type": "string",
                                        "description": "Data de fim (Y-m-d)"
                                    },
                                    "hora_inicio": {
                                        "type": "string",
                                        "description": "Hora de início (H:i)"
                                    },
                                    "hora_fim": {
                                        "type": "string",
                                        "description": "Hora de fim (H:i)"
                                    },
                                    "vagas_maximas": {
                                        "type": "integer",
                                        "description": "Limite total de vagas"
                                    },
                                    "permitir_escolha_assento": {
                                        "type": "boolean",
                                        "description": "Cliente escolhe assento"
                                    },
                                    "escolha_assento_dias_antes": {
                                        "type": "integer",
                                        "description": "Dias antes do embarque para liberar escolha"
                                    },
                                    "permitir_troca_transporte": {
                                        "type": "boolean",
                                        "description": "Permite trocar de transporte"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "rascunho (default), publicada, cancelada, finalizada"
                                    },
                                    "categoria_ids": {
                                        "type": "array",
                                        "description": "Array de IDs de categorias de passageiro"
                                    },
                                    "parcelas_max": {
                                        "type": "integer",
                                        "description": "Máximo de parcelas no checkout"
                                    },
                                    "acrescimo_tipo": {
                                        "type": "string",
                                        "description": "percentual ou fixo"
                                    },
                                    "acrescimo_parcela": {
                                        "type": "number",
                                        "description": "Taxa de parcelamento"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações gerais"
                                    },
                                    "duracao_noites": {
                                        "type": "integer",
                                        "description": "Pacote: duração em noites"
                                    },
                                    "destino_cidade": {
                                        "type": "string",
                                        "description": "Pacote: cidade destino"
                                    },
                                    "destino_estado": {
                                        "type": "string",
                                        "description": "Pacote: estado destino"
                                    },
                                    "destino_pais": {
                                        "type": "string",
                                        "description": "Pacote: país destino"
                                    },
                                    "regime_hospedagem": {
                                        "type": "string",
                                        "description": "Pacote: cafe_da_manha, meia_pensao, all_inclusive..."
                                    },
                                    "categoria_hotel": {
                                        "type": "string",
                                        "description": "Pacote: 3_estrelas, 4_estrelas, 5_estrelas"
                                    },
                                    "nome_hotel": {
                                        "type": "string",
                                        "description": "Pacote: nome do hotel"
                                    },
                                    "incluso": {
                                        "type": "array",
                                        "description": "Pacote: itens inclusos (array de strings)"
                                    },
                                    "nao_incluso": {
                                        "type": "array",
                                        "description": "Pacote: itens não inclusos"
                                    },
                                    "documentos_necessarios": {
                                        "type": "string",
                                        "description": "Pacote: documentos para embarque"
                                    },
                                    "observacoes_pacote": {
                                        "type": "string",
                                        "description": "Pacote: observações específicas"
                                    },
                                    "mostrar_site": {
                                        "type": "boolean",
                                        "description": "Publicar na vitrine pública"
                                    },
                                    "mostrar_vagas_disponiveis": {
                                        "type": "boolean",
                                        "description": "Mostrar \"X vagas restantes\" no público"
                                    },
                                    "vagas_alerta_poucas": {
                                        "type": "integer",
                                        "description": "Alerta amarelo \"últimas N\" (gatilho urgência)"
                                    },
                                    "vagas_alerta_ultimas": {
                                        "type": "integer",
                                        "description": "Alerta vermelho \"últimas N\" (urgência crítica)"
                                    },
                                    "vagas_reservadas": {
                                        "type": "integer",
                                        "description": "Vagas pré-reservadas (debitam de vagas_maximas)"
                                    },
                                    "desativar_vendas_dias_antes": {
                                        "type": "integer",
                                        "description": "Dias antes da viagem para fechar vendas"
                                    },
                                    "prazo_pagamento_minutos": {
                                        "type": "integer",
                                        "description": "Minutos para expirar reserva sem pagamento"
                                    },
                                    "observacoes_internas": {
                                        "type": "string",
                                        "description": "Observações privadas (não vão pro cliente)"
                                    },
                                    "exigir_contrato": {
                                        "type": "boolean",
                                        "description": "Forçar aceite de contrato no checkout"
                                    },
                                    "exigir_documentos": {
                                        "type": "boolean",
                                        "description": "Exigir upload de documentos antes do embarque"
                                    },
                                    "incluir_observacoes_no_cartao": {
                                        "type": "boolean",
                                        "description": "Incluir observações no cartão de embarque"
                                    },
                                    "duracao_dias": {
                                        "type": "integer",
                                        "description": "Duração em dias (display)"
                                    },
                                    "recorrencia_config": {
                                        "type": "object",
                                        "description": "Config de série semanal/mensal"
                                    },
                                    "recorrencia_ativa": {
                                        "type": "boolean",
                                        "description": "Toggle de geração automática da série"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço completo"
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude (-90..90)"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude (-180..180)"
                                    },
                                    "video": {
                                        "type": "string",
                                        "description": "URL de vídeo (YouTube/Vimeo)"
                                    },
                                    "contrato_template_id": {
                                        "type": "integer",
                                        "description": "ID do template de contrato a usar"
                                    },
                                    "whatsapp": {
                                        "type": "string",
                                        "description": "Número WhatsApp para esta excursão (ex: 5511999999999)"
                                    },
                                    "mostrar_whatsapp": {
                                        "type": "boolean",
                                        "description": "Exibir botão WhatsApp na página pública"
                                    },
                                    "modo_venda": {
                                        "type": "string",
                                        "description": "Modo de venda (ex: aberta, b2b, fechada)"
                                    },
                                    "modo_preco": {
                                        "type": "string",
                                        "description": "fixo (mostra preço), sob_consulta (esconde), hibrido"
                                    },
                                    "preco_display_modo": {
                                        "type": "string",
                                        "description": "Como exibir o preço público (a_partir_de, fixo, ate)"
                                    },
                                    "preco_display_intervalo": {
                                        "type": "boolean",
                                        "description": "Exibir intervalo mín-máx no público"
                                    },
                                    "escolha_assento_a_partir_de": {
                                        "type": "string",
                                        "description": "Data a partir da qual cliente pode escolher assento"
                                    },
                                    "guias_contam_vaga": {
                                        "type": "boolean",
                                        "description": "Guias ocupam vaga no transporte"
                                    },
                                    "publicar_em": {
                                        "type": "string",
                                        "description": "Publicar automaticamente nesta data"
                                    },
                                    "despublicar_em": {
                                        "type": "string",
                                        "description": "Despublicar automaticamente nesta data"
                                    },
                                    "seguro_link": {
                                        "type": "string",
                                        "description": "URL do seguro viagem (afiliado)"
                                    },
                                    "seguro_label": {
                                        "type": "string",
                                        "description": "Texto do botão de seguro"
                                    },
                                    "external_ref": {
                                        "type": "string",
                                        "description": "ID/código do seu sistema origem (ex: iBus-123)"
                                    },
                                    "external_source": {
                                        "type": "string",
                                        "description": "Nome do sistema origem (ex: ibus, sagtur)"
                                    },
                                    "categorias": {
                                        "type": "array",
                                        "description": "Lista de categorias a criar: [{nome*, descricao, idade_min, idade_max, ordem, ref}] — use `ref` como rótulo para referenciar em precos"
                                    },
                                    "transportes": {
                                        "type": "array",
                                        "description": "Lista de transportes a criar: [{veiculo_id*, nome, numero, tipo, vagas_total}]"
                                    },
                                    "embarques": {
                                        "type": "array",
                                        "description": "Lista de embarques: [{nome*, endereco, cidade, estado, hora_embarque, vagas_max, ref}] — use `ref` para referenciar em precos"
                                    },
                                    "precos": {
                                        "type": "array",
                                        "description": "Lista de preços: [{categoria_id|categoria_ref*, embarque_id|embarque_ref, valor*}] — pode usar ref das categorias/embarques criados na mesma chamada"
                                    },
                                    "conteudo": {
                                        "type": "object",
                                        "description": "Conteúdo da vitrine pública (page builder). Aceita: titulo, subtitulo, resumo, descricao_completa, atracoes[], o_que_esperar (string) ou o_que_esperar_items[], regras/regras_items[], o_que_levar/o_que_levar_items[], inclusos/inclusos_items[], nao_inclusos/nao_inclusos_items[], videos[], links[{titulo,url}], capa_url, banner_display_mode (hero|vitrine|split|minimal), meta_title, meta_description, status (rascunho|publicado). Detalhes em /excursoes/{id}/conteudo"
                                    }
                                },
                                "required": [
                                    "nome",
                                    "data_inicio"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{id}": {
            "get": {
                "tags": [
                    "Excursões"
                ],
                "summary": "Detalhes da excursão/pacote",
                "description": "Retorna a excursão/pacote com categorias, embarques, preços, guias, transportes, paradas. Use include=... para carregar relações adicionais (voos, cruzeiro, componentes, itinerario, cotacoes, allotments, vouchers).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "description": "CSV: voos,cruzeiro,componentes,itinerario,cotacoes,allotments,vouchers",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 45,
                                        "nome": "Gramado - Natal Luz 2025",
                                        "slug": "gramado-natal-luz-2025",
                                        "tipo_excursao": "excursao",
                                        "descricao": "Viagem completa com hospedagem...",
                                        "pais": "Brasil",
                                        "estado": "RS",
                                        "cidade": "Gramado",
                                        "data_inicio": "2025-12-20",
                                        "data_fim": "2025-12-24",
                                        "hora_inicio": "06:00",
                                        "hora_fim": "22:00",
                                        "status": "publicada",
                                        "vagas_maximas": 46,
                                        "permitir_escolha_assento": true,
                                        "escolha_assento_dias_antes": 30,
                                        "parcelas_max": 10,
                                        "acrescimo_tipo": "percentual",
                                        "acrescimo_parcela": 2.99,
                                        "duracao_noites": 4,
                                        "destino_cidade": "Gramado",
                                        "destino_estado": "RS",
                                        "destino_pais": "Brasil",
                                        "regime_hospedagem": "meia_pensao",
                                        "categoria_hotel": "4_estrelas",
                                        "nome_hotel": "Hotel Laghetto",
                                        "incluso": [
                                            "Hospedagem",
                                            "Café da manhã",
                                            "Transfer",
                                            "Passeios"
                                        ],
                                        "nao_incluso": [
                                            "Passeios opcionais",
                                            "Refeições extras"
                                        ],
                                        "documentos_necessarios": "RG ou CNH original",
                                        "categorias": [
                                            {
                                                "id": 1,
                                                "nome": "Adulto"
                                            },
                                            {
                                                "id": 2,
                                                "nome": "Criança (6-11)"
                                            }
                                        ],
                                        "embarques": [
                                            {
                                                "id": 12,
                                                "nome": "Terminal Tietê",
                                                "endereco": "Av. Cruzeiro do Sul, 1800",
                                                "cidade": "São Paulo",
                                                "estado": "SP",
                                                "hora_embarque": "06:00",
                                                "vagas_max": 46
                                            }
                                        ],
                                        "precos": [
                                            {
                                                "id": 77,
                                                "categoria_id": 1,
                                                "embarque_id": 12,
                                                "valor": 1450,
                                                "ativo": true
                                            }
                                        ],
                                        "transportes": [
                                            {
                                                "id": 9,
                                                "veiculo_id": 5,
                                                "nome": "Ônibus 1",
                                                "tipo": "onibus_leito",
                                                "vagas_total": 46,
                                                "veiculo": {
                                                    "id": 5,
                                                    "modelo": "Paradiso 1600",
                                                    "placa": "ABC-1234",
                                                    "capacidade_total": 46
                                                }
                                            }
                                        ],
                                        "paradas": [
                                            {
                                                "id": 3,
                                                "nome": "Café da manhã",
                                                "latitude": -26.9,
                                                "longitude": -49.07
                                            }
                                        ],
                                        "created_at": "2024-10-05T14:32:00Z",
                                        "updated_at": "2024-11-20T09:14:22Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Excursões"
                ],
                "summary": "Atualizar excursão",
                "description": "Atualiza parcialmente uma excursão. **Aceita todos os campos do POST** (todos opcionais). Envie só os que deseja alterar. Também aceita `conteudo` inline pra atualizar a vitrine pública na mesma chamada.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Excursão atualizada com sucesso.",
                                    "data": {
                                        "id": 45,
                                        "nome": "Excursão Atualizada",
                                        "status": "publicada"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome"
                                    },
                                    "slug": {
                                        "type": "string",
                                        "description": "Slug"
                                    },
                                    "tipo_excursao": {
                                        "type": "string",
                                        "description": "excursao ou pacote_viagem"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição"
                                    },
                                    "imagem": {
                                        "type": "string",
                                        "description": "URL da imagem principal"
                                    },
                                    "galeria": {
                                        "type": "array",
                                        "description": "Array de URLs"
                                    },
                                    "pais": {
                                        "type": "string",
                                        "description": "País"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "Estado"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "local": {
                                        "type": "string",
                                        "description": "Local"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço"
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude"
                                    },
                                    "data_inicio": {
                                        "type": "string",
                                        "description": "Data início"
                                    },
                                    "data_fim": {
                                        "type": "string",
                                        "description": "Data fim"
                                    },
                                    "hora_inicio": {
                                        "type": "string",
                                        "description": "Hora início"
                                    },
                                    "hora_fim": {
                                        "type": "string",
                                        "description": "Hora fim"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "rascunho, publicada, cancelada, finalizada"
                                    },
                                    "publicar_em": {
                                        "type": "string",
                                        "description": "Publicar nesta data"
                                    },
                                    "despublicar_em": {
                                        "type": "string",
                                        "description": "Despublicar nesta data"
                                    },
                                    "vagas_maximas": {
                                        "type": "integer",
                                        "description": "Vagas máximas"
                                    },
                                    "vagas_reservadas": {
                                        "type": "integer",
                                        "description": "Vagas pré-reservadas"
                                    },
                                    "mostrar_site": {
                                        "type": "boolean",
                                        "description": "Publicar na vitrine"
                                    },
                                    "mostrar_vagas_disponiveis": {
                                        "type": "boolean",
                                        "description": "Mostrar contador de vagas"
                                    },
                                    "vagas_alerta_poucas": {
                                        "type": "integer",
                                        "description": "Alerta urgência (amarelo)"
                                    },
                                    "vagas_alerta_ultimas": {
                                        "type": "integer",
                                        "description": "Alerta urgência (vermelho)"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações públicas"
                                    },
                                    "observacoes_internas": {
                                        "type": "string",
                                        "description": "Observações internas"
                                    },
                                    "incluir_observacoes_no_cartao": {
                                        "type": "boolean",
                                        "description": "Imprimir no cartão"
                                    },
                                    "exigir_contrato": {
                                        "type": "boolean",
                                        "description": "Forçar aceite contrato"
                                    },
                                    "exigir_documentos": {
                                        "type": "boolean",
                                        "description": "Forçar upload docs"
                                    },
                                    "contrato_template_id": {
                                        "type": "integer",
                                        "description": "Template do contrato"
                                    },
                                    "desativar_vendas_dias_antes": {
                                        "type": "integer",
                                        "description": "Dias para fechar vendas"
                                    },
                                    "prazo_pagamento_minutos": {
                                        "type": "integer",
                                        "description": "Minutos pra expirar reserva"
                                    },
                                    "duracao_dias": {
                                        "type": "integer",
                                        "description": "Duração em dias"
                                    },
                                    "recorrencia_config": {
                                        "type": "object",
                                        "description": "Config série"
                                    },
                                    "recorrencia_ativa": {
                                        "type": "boolean",
                                        "description": "Toggle série"
                                    },
                                    "permitir_escolha_assento": {
                                        "type": "boolean",
                                        "description": "Cliente escolhe"
                                    },
                                    "escolha_assento_dias_antes": {
                                        "type": "integer",
                                        "description": "Dias antes pra liberar"
                                    },
                                    "escolha_assento_a_partir_de": {
                                        "type": "string",
                                        "description": "Data específica"
                                    },
                                    "permitir_troca_transporte": {
                                        "type": "boolean",
                                        "description": "Troca de transporte"
                                    },
                                    "guias_contam_vaga": {
                                        "type": "boolean",
                                        "description": "Guia ocupa vaga"
                                    },
                                    "parcelas_max": {
                                        "type": "integer",
                                        "description": "Parcelas máx"
                                    },
                                    "acrescimo_tipo": {
                                        "type": "string",
                                        "description": "percentual ou fixo"
                                    },
                                    "acrescimo_parcela": {
                                        "type": "number",
                                        "description": "Taxa parcelamento"
                                    },
                                    "modo_preco": {
                                        "type": "string",
                                        "description": "fixo, sob_consulta, hibrido"
                                    },
                                    "preco_display_modo": {
                                        "type": "string",
                                        "description": "Display preço"
                                    },
                                    "preco_display_intervalo": {
                                        "type": "boolean",
                                        "description": "Intervalo público"
                                    },
                                    "video": {
                                        "type": "string",
                                        "description": "URL vídeo"
                                    },
                                    "whatsapp": {
                                        "type": "string",
                                        "description": "WhatsApp da viagem"
                                    },
                                    "mostrar_whatsapp": {
                                        "type": "boolean",
                                        "description": "Botão WhatsApp"
                                    },
                                    "duracao_noites": {
                                        "type": "integer",
                                        "description": "Pacote: noites"
                                    },
                                    "destino_cidade": {
                                        "type": "string",
                                        "description": "Pacote: cidade destino"
                                    },
                                    "destino_estado": {
                                        "type": "string",
                                        "description": "Pacote: estado"
                                    },
                                    "destino_pais": {
                                        "type": "string",
                                        "description": "Pacote: país"
                                    },
                                    "regime_hospedagem": {
                                        "type": "string",
                                        "description": "Pacote: regime"
                                    },
                                    "categoria_hotel": {
                                        "type": "string",
                                        "description": "Pacote: estrelas"
                                    },
                                    "nome_hotel": {
                                        "type": "string",
                                        "description": "Pacote: hotel"
                                    },
                                    "incluso": {
                                        "type": "array",
                                        "description": "Pacote: inclusos"
                                    },
                                    "nao_incluso": {
                                        "type": "array",
                                        "description": "Pacote: não inclusos"
                                    },
                                    "documentos_necessarios": {
                                        "type": "string",
                                        "description": "Pacote: documentos"
                                    },
                                    "observacoes_pacote": {
                                        "type": "string",
                                        "description": "Pacote: observações"
                                    },
                                    "seguro_link": {
                                        "type": "string",
                                        "description": "URL seguro"
                                    },
                                    "seguro_label": {
                                        "type": "string",
                                        "description": "Texto botão seguro"
                                    },
                                    "categoria_ids": {
                                        "type": "array",
                                        "description": "IDs de categorias (sync)"
                                    },
                                    "external_ref": {
                                        "type": "string",
                                        "description": "Ref do sistema origem"
                                    },
                                    "external_source": {
                                        "type": "string",
                                        "description": "Nome sistema origem"
                                    },
                                    "conteudo": {
                                        "type": "object",
                                        "description": "Conteúdo da vitrine pública (page builder). Ver schema completo em /excursoes/{id}/conteudo"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Excursões"
                ],
                "summary": "Excluir excursão",
                "description": "Remove uma excursão. Apenas excursões sem passageiros podem ser excluídas.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Excursão excluída com sucesso."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{id}/stats": {
            "get": {
                "tags": [
                    "Excursões"
                ],
                "summary": "Estatísticas da excursão",
                "description": "Retorna estatísticas agregadas: vagas, valores, confirmações.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "total_passageiros": 45,
                                        "passageiros_confirmados": 38,
                                        "vagas_total": 46,
                                        "vagas_ocupadas": 38,
                                        "vagas_disponiveis": 8,
                                        "preco_minimo": 1450,
                                        "preco_maximo": 1650
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/conteudo": {
            "get": {
                "tags": [
                    "Conteúdo (Excursão)"
                ],
                "summary": "Obter conteúdo da excursão",
                "description": "Retorna o conteúdo público da excursão (página da vitrine). Se ainda não foi criado, retorna estrutura vazia com defaults.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 22,
                                        "excursao_id": 45,
                                        "status": "publicado",
                                        "modo": "estruturado",
                                        "titulo": "Gramado Natal Luz 2026",
                                        "subtitulo": "5 dias de magia entre luzes e chocolate",
                                        "resumo": "Excursão completa com hospedagem, traslados e shows do Natal Luz.",
                                        "descricao_completa": "<p>HTML longo descritivo...</p>",
                                        "atracoes": [
                                            "Show Natal Luz",
                                            "Mini Mundo",
                                            "Lago Negro",
                                            "Rua Coberta"
                                        ],
                                        "o_que_esperar": "Hospedagem 4 noites\nCafé incluso\nGuia bilíngue",
                                        "o_que_esperar_array": [
                                            "Hospedagem 4 noites",
                                            "Café incluso",
                                            "Guia bilíngue"
                                        ],
                                        "regras": "Idade mínima 0 anos\nMenores acompanhados\nNão fumar no ônibus",
                                        "regras_array": [
                                            "Idade mínima 0 anos",
                                            "Menores acompanhados",
                                            "Não fumar no ônibus"
                                        ],
                                        "o_que_levar": "Documento RG\nAgasalho\nMedicamentos pessoais",
                                        "o_que_levar_array": [
                                            "Documento RG",
                                            "Agasalho",
                                            "Medicamentos pessoais"
                                        ],
                                        "inclusos": "Transporte ida e volta\nHospedagem 4 diárias\nCafé da manhã",
                                        "inclusos_array": [
                                            "Transporte ida e volta",
                                            "Hospedagem 4 diárias",
                                            "Café da manhã"
                                        ],
                                        "nao_inclusos": "Almoço e jantar\nBebidas\nDespesas extras",
                                        "nao_inclusos_array": [
                                            "Almoço e jantar",
                                            "Bebidas",
                                            "Despesas extras"
                                        ],
                                        "videos": [
                                            "https://youtu.be/abc123"
                                        ],
                                        "links": [
                                            {
                                                "titulo": "Mapa do roteiro",
                                                "url": "https://google.com/maps/..."
                                            }
                                        ],
                                        "capa_url": "https://cdn.../gramado-capa.jpg",
                                        "banner_display_mode": "hero",
                                        "meta_title": "Gramado Natal Luz 2026 — 5 dias inesquecíveis",
                                        "meta_description": "Venha viver a magia do Natal Luz com a melhor agência.",
                                        "meta_keywords": "gramado, natal luz, excursão"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Conteúdo (Excursão)"
                ],
                "summary": "Criar/atualizar conteúdo",
                "description": "Cria ou atualiza o conteúdo público (upsert por excursao_id). **Os 5 campos de lista** (`o_que_esperar`, `regras`, `o_que_levar`, `inclusos`, `nao_inclusos`) aceitam 2 formatos: string com `\\n` separador OU array via `{campo}_items[]` (será convertido automaticamente).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Conteúdo salvo com sucesso.",
                                    "data": {
                                        "id": 22,
                                        "excursao_id": 45,
                                        "status": "publicado",
                                        "titulo": "Gramado Natal Luz 2026",
                                        "atracoes": [
                                            "Show Natal Luz",
                                            "Mini Mundo",
                                            "Lago Negro"
                                        ],
                                        "inclusos_array": [
                                            "Transporte",
                                            "Hospedagem",
                                            "Café"
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "modo": {
                                        "type": "string",
                                        "description": "estruturado (default) ou livre (HTML único)"
                                    },
                                    "conteudo_livre": {
                                        "type": "string",
                                        "description": "HTML completo (só se modo=livre)"
                                    },
                                    "titulo": {
                                        "type": "string",
                                        "description": "Título do bloco principal"
                                    },
                                    "subtitulo": {
                                        "type": "string",
                                        "description": "Subtítulo"
                                    },
                                    "resumo": {
                                        "type": "string",
                                        "description": "Resumo curto"
                                    },
                                    "descricao_completa": {
                                        "type": "string",
                                        "description": "Descrição longa (HTML permitido)"
                                    },
                                    "atracoes": {
                                        "type": "array",
                                        "description": "Lista de atrações: [\"Praia X\", \"Centro Y\"]"
                                    },
                                    "legenda_atracoes": {
                                        "type": "string",
                                        "description": "Texto acima da lista de atrações"
                                    },
                                    "o_que_esperar": {
                                        "type": "string",
                                        "description": "Texto multilinha (1 item por linha)"
                                    },
                                    "o_que_esperar_items": {
                                        "type": "array",
                                        "description": "Alternativa: array de strings"
                                    },
                                    "legenda_o_que_esperar": {
                                        "type": "string",
                                        "description": "Texto acima"
                                    },
                                    "regras": {
                                        "type": "string",
                                        "description": "Regras e normas (multilinha)"
                                    },
                                    "regras_items": {
                                        "type": "array",
                                        "description": "Alternativa array"
                                    },
                                    "legenda_regras": {
                                        "type": "string",
                                        "description": "Texto acima"
                                    },
                                    "o_que_levar": {
                                        "type": "string",
                                        "description": "Itens a levar (multilinha)"
                                    },
                                    "o_que_levar_items": {
                                        "type": "array",
                                        "description": "Alternativa array"
                                    },
                                    "inclusos": {
                                        "type": "string",
                                        "description": "Itens inclusos (multilinha)"
                                    },
                                    "inclusos_items": {
                                        "type": "array",
                                        "description": "Alternativa array"
                                    },
                                    "nao_inclusos": {
                                        "type": "string",
                                        "description": "Itens não inclusos (multilinha)"
                                    },
                                    "nao_inclusos_items": {
                                        "type": "array",
                                        "description": "Alternativa array"
                                    },
                                    "videos": {
                                        "type": "array",
                                        "description": "URLs YouTube/Vimeo"
                                    },
                                    "legenda_videos": {
                                        "type": "string",
                                        "description": "Texto acima dos vídeos"
                                    },
                                    "links": {
                                        "type": "array",
                                        "description": "Links: [{titulo, url}]"
                                    },
                                    "titulo_galeria": {
                                        "type": "string",
                                        "description": "Título da galeria"
                                    },
                                    "legenda_galeria": {
                                        "type": "string",
                                        "description": "Texto acima da galeria"
                                    },
                                    "ingressos_ids": {
                                        "type": "array",
                                        "description": "IDs de ingressos do tenant a exibir"
                                    },
                                    "legenda_ingressos": {
                                        "type": "string",
                                        "description": "Texto acima"
                                    },
                                    "capa_url": {
                                        "type": "string",
                                        "description": "URL da imagem de capa"
                                    },
                                    "banner_display_mode": {
                                        "type": "string",
                                        "description": "hero | vitrine | split | minimal"
                                    },
                                    "meta_title": {
                                        "type": "string",
                                        "description": "SEO: título da página"
                                    },
                                    "meta_description": {
                                        "type": "string",
                                        "description": "SEO: meta description (até 500 chars)"
                                    },
                                    "meta_keywords": {
                                        "type": "string",
                                        "description": "SEO: keywords"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "rascunho (default) ou publicado"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/conteudo/publicar": {
            "post": {
                "tags": [
                    "Conteúdo (Excursão)"
                ],
                "summary": "Publicar conteúdo",
                "description": "Marca o conteúdo como `publicado`. Necessário pra aparecer na vitrine pública.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Conteúdo publicado."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/conteudo/despublicar": {
            "post": {
                "tags": [
                    "Conteúdo (Excursão)"
                ],
                "summary": "Despublicar conteúdo",
                "description": "Volta o status para `rascunho` — o conteúdo deixa de aparecer na vitrine pública (mas a excursão pode continuar publicada).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Conteúdo despublicado."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/fotos": {
            "get": {
                "tags": [
                    "Fotos & Capa (Excursão)"
                ],
                "summary": "Listar fotos da galeria",
                "description": "Retorna as fotos da galeria ordenadas. Inclui URL pública, thumbnail, legenda e flag de destaque.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 12,
                                            "excursao_id": 45,
                                            "url": "https://.../storage/tenants/X/excursoes/45/foto1.webp",
                                            "thumbnail_url": "https://.../storage/tenants/X/excursoes/45/foto1_thumb.webp",
                                            "legenda": "Vista da praia",
                                            "alt_text": "Praia ao pôr do sol",
                                            "destaque": false,
                                            "ordem": 1,
                                            "largura": 1920,
                                            "altura": 1280,
                                            "tamanho": 245000
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Fotos & Capa (Excursão)"
                ],
                "summary": "Adicionar foto à galeria (upload ou URL)",
                "description": "Aceita 2 caminhos: **(a)** multipart/form-data com campo `foto` (arquivo binário) **OU (b)** application/json com campo `url` (URL externa que será baixada e re-hospedada). Limite: 10 fotos por excursão. Validações de segurança: extensão whitelist (jpg/jpeg/png/webp/gif), MIME real via finfo, magic bytes via getimagesize, dimensões máx 8000x8000, anti-SSRF na URL externa (bloqueia IPs privados).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Foto adicionada.",
                                    "data": {
                                        "id": 12,
                                        "url": "https://.../foto.webp",
                                        "thumbnail_url": "https://.../foto_thumb.webp",
                                        "ordem": 3
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "foto": {
                                        "type": "string",
                                        "description": "Arquivo da foto (jpg/png/webp/gif, máx 10MB). multipart/form-data. Use ESTE ou `url`, não os dois."
                                    },
                                    "url": {
                                        "type": "string",
                                        "description": "URL pública da imagem (será baixada e re-hospedada). Apenas HTTP/HTTPS, IPs privados bloqueados."
                                    },
                                    "legenda": {
                                        "type": "string",
                                        "description": "Legenda visível na vitrine"
                                    },
                                    "alt_text": {
                                        "type": "string",
                                        "description": "Texto alternativo (SEO/acessibilidade)"
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": "Marcar como destaque"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/fotos/{id}": {
            "put": {
                "tags": [
                    "Fotos & Capa (Excursão)"
                ],
                "summary": "Atualizar dados da foto",
                "description": "Edita legenda, alt_text, destaque ou ordem de uma foto existente.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da foto",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Foto atualizada."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "legenda": {
                                        "type": "string",
                                        "description": "Legenda"
                                    },
                                    "alt_text": {
                                        "type": "string",
                                        "description": "Texto alternativo"
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": "Destaque"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Posição na galeria (1-N)"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Fotos & Capa (Excursão)"
                ],
                "summary": "Remover foto",
                "description": "Remove a foto da galeria e apaga os arquivos do storage.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da foto",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Foto removida."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/fotos/reorder": {
            "post": {
                "tags": [
                    "Fotos & Capa (Excursão)"
                ],
                "summary": "Reordenar galeria",
                "description": "Atualiza a ordem de exibição das fotos. Envie o array `ordem` com os IDs na sequência desejada (índice 0 = primeira posição).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Ordem atualizada."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ordem": {
                                        "type": "array",
                                        "description": "Array de IDs na ordem desejada: [42, 41, 43, ...]"
                                    }
                                },
                                "required": [
                                    "ordem"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/capa": {
            "post": {
                "tags": [
                    "Fotos & Capa (Excursão)"
                ],
                "summary": "Upload da capa",
                "description": "Define a imagem de capa da excursão (renderizada como banner). Aceita multipart (`capa`) OU URL externa (`url`). A URL externa não é re-hospedada (fica como apontamento), mas passa por validação anti-SSRF e content-type. Para garantia de disponibilidade, prefira upload multipart.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Capa atualizada.",
                                    "data": {
                                        "capa_url": "https://.../storage/.../capa.jpg"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "capa": {
                                        "type": "string",
                                        "description": "Arquivo da capa (jpg/png/webp/gif, máx 5MB)"
                                    },
                                    "url": {
                                        "type": "string",
                                        "description": "URL pública da capa (alternativa ao upload)"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/categorias": {
            "get": {
                "tags": [
                    "Categorias (Excursão)"
                ],
                "summary": "Listar categorias da excursão",
                "description": "Retorna as categorias cadastradas para a excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 197,
                                            "excursao_id": 70,
                                            "nome": "Adulto",
                                            "descricao": "Passageiro adulto",
                                            "idade_min": 18,
                                            "idade_max": null,
                                            "ordem": 1,
                                            "vagas_max_categoria": null,
                                            "qtd_passageiros": 1,
                                            "requer_documento": false,
                                            "documento_tipo": null,
                                            "ativo": true,
                                            "vagas_ocupadas": 0,
                                            "vagas_disponiveis": null,
                                            "created_at": "2026-04-21T20:44:47.000000Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Categorias (Excursão)"
                ],
                "summary": "Criar categoria",
                "description": "Cria uma nova categoria vinculada à excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Categoria criada com sucesso.",
                                    "data": {
                                        "id": 197,
                                        "excursao_id": 70,
                                        "nome": "Adulto",
                                        "descricao": "Passageiro adulto",
                                        "idade_min": 18,
                                        "idade_max": null,
                                        "ordem": 1,
                                        "vagas_max_categoria": null,
                                        "qtd_passageiros": 1,
                                        "requer_documento": false,
                                        "documento_tipo": null,
                                        "ativo": true,
                                        "vagas_ocupadas": 0,
                                        "vagas_disponiveis": null,
                                        "created_at": "2026-04-21T20:44:47.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome da categoria (ex: Adulto, Criança, Idoso)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição da categoria"
                                    },
                                    "idade_min": {
                                        "type": "integer",
                                        "description": "Idade mínima"
                                    },
                                    "idade_max": {
                                        "type": "integer",
                                        "description": "Idade máxima"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição (1, 2, 3...)"
                                    },
                                    "vagas_max_categoria": {
                                        "type": "integer",
                                        "description": "Limite de vagas para esta categoria"
                                    },
                                    "qtd_passageiros": {
                                        "type": "integer",
                                        "description": "Quantos passageiros ocupam (default 1; use 0 para bebê de colo)"
                                    },
                                    "requer_documento": {
                                        "type": "boolean",
                                        "description": "Exige documento específico"
                                    },
                                    "documento_tipo": {
                                        "type": "string",
                                        "description": "Tipo do documento exigido"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Categoria ativa"
                                    }
                                },
                                "required": [
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/categorias/{id}": {
            "get": {
                "tags": [
                    "Categorias (Excursão)"
                ],
                "summary": "Detalhes da categoria",
                "description": "Retorna uma categoria específica.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da categoria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 197,
                                        "excursao_id": 70,
                                        "nome": "Adulto",
                                        "descricao": "Passageiro adulto",
                                        "idade_min": 18,
                                        "idade_max": null,
                                        "ordem": 1,
                                        "vagas_max_categoria": null,
                                        "qtd_passageiros": 1,
                                        "requer_documento": false,
                                        "documento_tipo": null,
                                        "ativo": true,
                                        "vagas_ocupadas": 0,
                                        "vagas_disponiveis": null,
                                        "created_at": "2026-04-21T20:44:47.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Categorias (Excursão)"
                ],
                "summary": "Atualizar categoria",
                "description": "Atualiza parcialmente uma categoria.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da categoria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Categoria atualizada.",
                                    "data": {
                                        "id": 197,
                                        "excursao_id": 70,
                                        "nome": "Adulto",
                                        "descricao": "Passageiro adulto",
                                        "idade_min": 18,
                                        "idade_max": null,
                                        "ordem": 1,
                                        "vagas_max_categoria": null,
                                        "qtd_passageiros": 1,
                                        "requer_documento": false,
                                        "documento_tipo": null,
                                        "ativo": true,
                                        "vagas_ocupadas": 0,
                                        "vagas_disponiveis": null,
                                        "created_at": "2026-04-21T20:44:47.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome da categoria (ex: Adulto, Criança, Idoso)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição da categoria"
                                    },
                                    "idade_min": {
                                        "type": "integer",
                                        "description": "Idade mínima"
                                    },
                                    "idade_max": {
                                        "type": "integer",
                                        "description": "Idade máxima"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição (1, 2, 3...)"
                                    },
                                    "vagas_max_categoria": {
                                        "type": "integer",
                                        "description": "Limite de vagas para esta categoria"
                                    },
                                    "qtd_passageiros": {
                                        "type": "integer",
                                        "description": "Quantos passageiros ocupam (default 1; use 0 para bebê de colo)"
                                    },
                                    "requer_documento": {
                                        "type": "boolean",
                                        "description": "Exige documento específico"
                                    },
                                    "documento_tipo": {
                                        "type": "string",
                                        "description": "Tipo do documento exigido"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Categoria ativa"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Categorias (Excursão)"
                ],
                "summary": "Excluir categoria",
                "description": "Remove uma categoria.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da categoria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Categoria excluída."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/categorias/reorder": {
            "post": {
                "tags": [
                    "Categorias (Excursão)"
                ],
                "summary": "Reordenar categorias",
                "description": "Reordena a exibição das categorias.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Categorias reordenadas."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ordem": {
                                        "type": "array",
                                        "description": "Array de IDs na nova ordem: [id1, id2, id3]"
                                    }
                                },
                                "required": [
                                    "ordem"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/embarques": {
            "get": {
                "tags": [
                    "Embarques (Excursão)"
                ],
                "summary": "Listar embarques",
                "description": "Retorna todos os pontos de embarque da excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 188,
                                            "excursao_id": 70,
                                            "nome": "Terminal Tietê",
                                            "endereco": "Av. Cruzeiro do Sul, 1800",
                                            "cidade": "São Paulo",
                                            "estado": "SP",
                                            "cep": "02036-100",
                                            "referencia": "Plataforma 35",
                                            "hora_embarque": "05:00",
                                            "hora_retorno": "23:00",
                                            "data_embarque": "2026-11-15",
                                            "tolerancia_minutos": 15,
                                            "latitude": null,
                                            "longitude": null,
                                            "transporte_id": null,
                                            "permite_reserva_online": true,
                                            "vagas_max": null,
                                            "ordem": 1,
                                            "ativo": true,
                                            "created_at": "2026-04-21T20:44:17.000000Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Embarques (Excursão)"
                ],
                "summary": "Criar embarque",
                "description": "Cadastra um novo ponto de embarque.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Embarque criado.",
                                    "data": {
                                        "id": 188,
                                        "excursao_id": 70,
                                        "nome": "Terminal Tietê",
                                        "endereco": "Av. Cruzeiro do Sul, 1800",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "cep": "02036-100",
                                        "referencia": "Plataforma 35",
                                        "hora_embarque": "05:00",
                                        "hora_retorno": "23:00",
                                        "data_embarque": "2026-11-15",
                                        "tolerancia_minutos": 15,
                                        "latitude": null,
                                        "longitude": null,
                                        "transporte_id": null,
                                        "permite_reserva_online": true,
                                        "vagas_max": null,
                                        "ordem": 1,
                                        "ativo": true,
                                        "created_at": "2026-04-21T20:44:17.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do ponto (ex: Terminal Tietê)"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço completo"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "referencia": {
                                        "type": "string",
                                        "description": "Ponto de referência"
                                    },
                                    "hora_embarque": {
                                        "type": "string",
                                        "description": "Horário de embarque (H:i)"
                                    },
                                    "hora_retorno": {
                                        "type": "string",
                                        "description": "Horário de retorno (H:i)"
                                    },
                                    "data_embarque": {
                                        "type": "string",
                                        "description": "Data específica (sobrescreve data_inicio da excursão)"
                                    },
                                    "tolerancia_minutos": {
                                        "type": "integer",
                                        "description": "Tolerância de atraso em minutos"
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude do ponto"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude do ponto"
                                    },
                                    "transporte_id": {
                                        "type": "integer",
                                        "description": "ID do transporte específico (se múltiplos)"
                                    },
                                    "permite_reserva_online": {
                                        "type": "boolean",
                                        "description": "Permite reserva online (default true)"
                                    },
                                    "vagas_max": {
                                        "type": "integer",
                                        "description": "Limite de vagas por este embarque"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Embarque ativo"
                                    }
                                },
                                "required": [
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/embarques/{id}": {
            "get": {
                "tags": [
                    "Embarques (Excursão)"
                ],
                "summary": "Detalhes do embarque",
                "description": "Retorna um ponto de embarque.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do embarque",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 188,
                                        "excursao_id": 70,
                                        "nome": "Terminal Tietê",
                                        "endereco": "Av. Cruzeiro do Sul, 1800",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "cep": "02036-100",
                                        "referencia": "Plataforma 35",
                                        "hora_embarque": "05:00",
                                        "hora_retorno": "23:00",
                                        "data_embarque": "2026-11-15",
                                        "tolerancia_minutos": 15,
                                        "latitude": null,
                                        "longitude": null,
                                        "transporte_id": null,
                                        "permite_reserva_online": true,
                                        "vagas_max": null,
                                        "ordem": 1,
                                        "ativo": true,
                                        "created_at": "2026-04-21T20:44:17.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Embarques (Excursão)"
                ],
                "summary": "Atualizar embarque",
                "description": "Atualiza parcialmente um ponto de embarque.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do embarque",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Embarque atualizado.",
                                    "data": {
                                        "id": 188,
                                        "excursao_id": 70,
                                        "nome": "Terminal Tietê",
                                        "endereco": "Av. Cruzeiro do Sul, 1800",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "cep": "02036-100",
                                        "referencia": "Plataforma 35",
                                        "hora_embarque": "05:00",
                                        "hora_retorno": "23:00",
                                        "data_embarque": "2026-11-15",
                                        "tolerancia_minutos": 15,
                                        "latitude": null,
                                        "longitude": null,
                                        "transporte_id": null,
                                        "permite_reserva_online": true,
                                        "vagas_max": null,
                                        "ordem": 1,
                                        "ativo": true,
                                        "created_at": "2026-04-21T20:44:17.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do ponto (ex: Terminal Tietê)"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço completo"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "referencia": {
                                        "type": "string",
                                        "description": "Ponto de referência"
                                    },
                                    "hora_embarque": {
                                        "type": "string",
                                        "description": "Horário de embarque (H:i)"
                                    },
                                    "hora_retorno": {
                                        "type": "string",
                                        "description": "Horário de retorno (H:i)"
                                    },
                                    "data_embarque": {
                                        "type": "string",
                                        "description": "Data específica (sobrescreve data_inicio da excursão)"
                                    },
                                    "tolerancia_minutos": {
                                        "type": "integer",
                                        "description": "Tolerância de atraso em minutos"
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude do ponto"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude do ponto"
                                    },
                                    "transporte_id": {
                                        "type": "integer",
                                        "description": "ID do transporte específico (se múltiplos)"
                                    },
                                    "permite_reserva_online": {
                                        "type": "boolean",
                                        "description": "Permite reserva online (default true)"
                                    },
                                    "vagas_max": {
                                        "type": "integer",
                                        "description": "Limite de vagas por este embarque"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Embarque ativo"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Embarques (Excursão)"
                ],
                "summary": "Excluir embarque",
                "description": "Remove um ponto de embarque.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do embarque",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Embarque excluído."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/embarques/reorder": {
            "post": {
                "tags": [
                    "Embarques (Excursão)"
                ],
                "summary": "Reordenar embarques",
                "description": "Reordena a exibição dos embarques.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Embarques reordenados."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ordem": {
                                        "type": "array",
                                        "description": "Array de IDs na nova ordem"
                                    }
                                },
                                "required": [
                                    "ordem"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/precos": {
            "get": {
                "tags": [
                    "Preços (Excursão)"
                ],
                "summary": "Listar preços",
                "description": "Retorna todos os preços (categoria × embarque) da excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 371,
                                            "excursao_id": 70,
                                            "categoria_id": 197,
                                            "embarque_id": 188,
                                            "valor": 250,
                                            "valor_ate": null,
                                            "valor_aumenta_em": null,
                                            "permite_reserva_online": true,
                                            "ativo": true,
                                            "categoria": {
                                                "id": 197,
                                                "nome": "Adulto"
                                            },
                                            "embarque": {
                                                "id": 188,
                                                "nome": "Terminal Tietê"
                                            },
                                            "created_at": "2026-04-21T20:44:57.000000Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Preços (Excursão)"
                ],
                "summary": "Criar preço",
                "description": "Cadastra um preço vinculado a uma categoria (e opcionalmente a um embarque).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Preço criado.",
                                    "data": {
                                        "id": 371,
                                        "excursao_id": 70,
                                        "categoria_id": 197,
                                        "embarque_id": 188,
                                        "valor": 250,
                                        "valor_ate": null,
                                        "valor_aumenta_em": null,
                                        "permite_reserva_online": true,
                                        "ativo": true,
                                        "categoria": {
                                            "id": 197,
                                            "nome": "Adulto"
                                        },
                                        "embarque": {
                                            "id": 188,
                                            "nome": "Terminal Tietê"
                                        },
                                        "created_at": "2026-04-21T20:44:57.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "categoria_id": {
                                        "type": "integer",
                                        "description": "ID da categoria (Adulto, Criança, etc)"
                                    },
                                    "embarque_id": {
                                        "type": "integer",
                                        "description": "ID do embarque (permite preço diferente por ponto)"
                                    },
                                    "valor": {
                                        "type": "number",
                                        "description": "Valor atual cobrado (R$)"
                                    },
                                    "valor_ate": {
                                        "type": "number",
                                        "description": "Valor limite quando há reajuste progressivo"
                                    },
                                    "valor_aumenta_em": {
                                        "type": "string",
                                        "description": "Data em que o valor passa para valor_ate"
                                    },
                                    "permite_reserva_online": {
                                        "type": "boolean",
                                        "description": "Permite reserva online (default true)"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Preço ativo"
                                    }
                                },
                                "required": [
                                    "categoria_id",
                                    "valor"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/precos/{id}": {
            "get": {
                "tags": [
                    "Preços (Excursão)"
                ],
                "summary": "Detalhes do preço",
                "description": "Retorna um preço específico.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do preço",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 371,
                                        "excursao_id": 70,
                                        "categoria_id": 197,
                                        "embarque_id": 188,
                                        "valor": 250,
                                        "valor_ate": null,
                                        "valor_aumenta_em": null,
                                        "permite_reserva_online": true,
                                        "ativo": true,
                                        "categoria": {
                                            "id": 197,
                                            "nome": "Adulto"
                                        },
                                        "embarque": {
                                            "id": 188,
                                            "nome": "Terminal Tietê"
                                        },
                                        "created_at": "2026-04-21T20:44:57.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Preços (Excursão)"
                ],
                "summary": "Atualizar preço",
                "description": "Atualiza parcialmente um preço.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do preço",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Preço atualizado.",
                                    "data": {
                                        "id": 371,
                                        "excursao_id": 70,
                                        "categoria_id": 197,
                                        "embarque_id": 188,
                                        "valor": 250,
                                        "valor_ate": null,
                                        "valor_aumenta_em": null,
                                        "permite_reserva_online": true,
                                        "ativo": true,
                                        "categoria": {
                                            "id": 197,
                                            "nome": "Adulto"
                                        },
                                        "embarque": {
                                            "id": 188,
                                            "nome": "Terminal Tietê"
                                        },
                                        "created_at": "2026-04-21T20:44:57.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "categoria_id": {
                                        "type": "integer",
                                        "description": "ID da categoria (Adulto, Criança, etc)"
                                    },
                                    "embarque_id": {
                                        "type": "integer",
                                        "description": "ID do embarque (permite preço diferente por ponto)"
                                    },
                                    "valor": {
                                        "type": "number",
                                        "description": "Valor atual cobrado (R$)"
                                    },
                                    "valor_ate": {
                                        "type": "number",
                                        "description": "Valor limite quando há reajuste progressivo"
                                    },
                                    "valor_aumenta_em": {
                                        "type": "string",
                                        "description": "Data em que o valor passa para valor_ate"
                                    },
                                    "permite_reserva_online": {
                                        "type": "boolean",
                                        "description": "Permite reserva online (default true)"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Preço ativo"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Preços (Excursão)"
                ],
                "summary": "Excluir preço",
                "description": "Remove um preço.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do preço",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Preço excluído."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/precos/bulk": {
            "patch": {
                "tags": [
                    "Preços (Excursão)"
                ],
                "summary": "Atualização em massa de preços",
                "description": "Atualiza múltiplos preços em uma única chamada. Útil para reajustes.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Preços atualizados.",
                                    "data": {
                                        "atualizados": 4
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "precos": {
                                        "type": "array",
                                        "description": "Lista: [{id*, valor?, valor_ate?, valor_aumenta_em?, ativo?}]"
                                    }
                                },
                                "required": [
                                    "precos"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/variacoes": {
            "get": {
                "tags": [
                    "Variações"
                ],
                "summary": "Listar variações",
                "description": "Retorna as variações da excursão, na ordem definida no painel, com a faixa de preço e a ocupação de cada uma. Em excursão que não é pacote de viagem a lista volta vazia.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "ativas",
                        "in": "query",
                        "required": false,
                        "description": "Quando 1, retorna apenas as variações ativas",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 82,
                                            "excursao_id": 39,
                                            "nome": "Quarto DUPLO + Bike Mecânica",
                                            "descricao": null,
                                            "tipo": "generica",
                                            "tipo_label": "Genérica",
                                            "codigo": null,
                                            "ordem": 4,
                                            "ativa": true,
                                            "vagas_maximas": null,
                                            "vagas_ocupadas": 6,
                                            "vagas_disponiveis": null,
                                            "fornecedor_id": null,
                                            "precos": {
                                                "quantidade": 1,
                                                "menor": 1990,
                                                "maior": 1990
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Variações"
                ],
                "summary": "Criar variação",
                "description": "Cria uma variação na excursão. Entra no fim da lista. Recusa com 422 quando a excursão não é pacote de viagem (TIPO_NAO_SUPORTA_VARIACAO) ou quando o código já existe na mesma excursão (DUPLICATE_CODE).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Variação criada com sucesso",
                                    "data": {
                                        "id": 82,
                                        "excursao_id": 39,
                                        "nome": "Quarto DUPLO + Bike Mecânica",
                                        "descricao": null,
                                        "tipo": "generica",
                                        "tipo_label": "Genérica",
                                        "codigo": null,
                                        "ordem": 4,
                                        "ativa": true,
                                        "vagas_maximas": null,
                                        "vagas_ocupadas": 6,
                                        "vagas_disponiveis": null,
                                        "fornecedor_id": null,
                                        "precos": {
                                            "quantidade": 1,
                                            "menor": 1990,
                                            "maior": 1990
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome exibido ao cliente (ex: Leito, Semi-leito, Quarto DUPLO + Bike Mecânica)"
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "hospedagem, acomodacao, refeicao, transporte ou generica"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Detalhamento do que está incluído"
                                    },
                                    "codigo": {
                                        "type": "string",
                                        "description": "Código interno. Deve ser único dentro da excursão"
                                    },
                                    "ativa": {
                                        "type": "boolean",
                                        "description": "Disponível para venda (default true)"
                                    },
                                    "vagas_maximas": {
                                        "type": "integer",
                                        "description": "Limite de vagas desta variação. Nulo = sem limite"
                                    },
                                    "fornecedor_id": {
                                        "type": "integer",
                                        "description": "Fornecedor responsável por esta variação"
                                    },
                                    "metadata": {
                                        "type": "object",
                                        "description": "Campos livres do integrador"
                                    }
                                },
                                "required": [
                                    "nome",
                                    "tipo"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/variacoes/{id}": {
            "get": {
                "tags": [
                    "Variações"
                ],
                "summary": "Detalhar variação",
                "description": "Retorna uma variação específica da excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da variação",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 82,
                                        "excursao_id": 39,
                                        "nome": "Quarto DUPLO + Bike Mecânica",
                                        "descricao": null,
                                        "tipo": "generica",
                                        "tipo_label": "Genérica",
                                        "codigo": null,
                                        "ordem": 4,
                                        "ativa": true,
                                        "vagas_maximas": null,
                                        "vagas_ocupadas": 6,
                                        "vagas_disponiveis": null,
                                        "fornecedor_id": null,
                                        "precos": {
                                            "quantidade": 1,
                                            "menor": 1990,
                                            "maior": 1990
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Variações"
                ],
                "summary": "Atualizar variação",
                "description": "Atualização parcial: envie apenas os campos que quer mudar. Recusa com 422 ao reduzir vagas_maximas abaixo do que já foi vendido (LIMITE_ABAIXO_DO_VENDIDO). Para tirar da venda sem apagar histórico, envie ativa=false.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da variação",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Variação atualizada com sucesso",
                                    "data": {
                                        "id": 82,
                                        "excursao_id": 39,
                                        "nome": "Quarto DUPLO + Bike Mecânica",
                                        "descricao": null,
                                        "tipo": "generica",
                                        "tipo_label": "Genérica",
                                        "codigo": null,
                                        "ordem": 4,
                                        "ativa": true,
                                        "vagas_maximas": null,
                                        "vagas_ocupadas": 6,
                                        "vagas_disponiveis": null,
                                        "fornecedor_id": null,
                                        "precos": {
                                            "quantidade": 1,
                                            "menor": 1990,
                                            "maior": 1990
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome exibido ao cliente (ex: Leito, Semi-leito, Quarto DUPLO + Bike Mecânica)"
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "hospedagem, acomodacao, refeicao, transporte ou generica"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Detalhamento do que está incluído"
                                    },
                                    "codigo": {
                                        "type": "string",
                                        "description": "Código interno. Deve ser único dentro da excursão"
                                    },
                                    "ativa": {
                                        "type": "boolean",
                                        "description": "Disponível para venda (default true)"
                                    },
                                    "vagas_maximas": {
                                        "type": "integer",
                                        "description": "Limite de vagas desta variação. Nulo = sem limite"
                                    },
                                    "fornecedor_id": {
                                        "type": "integer",
                                        "description": "Fornecedor responsável por esta variação"
                                    },
                                    "metadata": {
                                        "type": "object",
                                        "description": "Campos livres do integrador"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Variações"
                ],
                "summary": "Remover variação",
                "description": "Remove a variação e os preços ligados a ela. Bloqueado com 422 quando já há passageiros na variação (VARIACAO_COM_PASSAGEIROS); nesse caso use ativa=false.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da variação",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Variação removida com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/dados": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Obter dados do pacote",
                "description": "Retorna dados gerais do pacote (país, cidade, hotel, regime, observações).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "pais": "Argentina",
                                        "estado": "Buenos Aires",
                                        "cidade": "Buenos Aires",
                                        "nome_hotel": "Hotel Madero",
                                        "categoria_hotel": "5 estrelas",
                                        "regime_hospedagem": "Café da manhã",
                                        "documentos_necessarios": "Passaporte ou RG válido",
                                        "observacoes_pacote": "Reembolso integral até 30 dias antes.",
                                        "duracao_noites": 5
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar dados do pacote",
                "description": "`duracao_noites` é calculada automaticamente pelas datas da excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Dados do pacote atualizados."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "pais": {
                                        "type": "string",
                                        "description": "Max 100"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "Max 100"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Max 100"
                                    },
                                    "nome_hotel": {
                                        "type": "string",
                                        "description": "Max 255"
                                    },
                                    "categoria_hotel": {
                                        "type": "string",
                                        "description": "Ex: 5 estrelas, Pousada"
                                    },
                                    "regime_hospedagem": {
                                        "type": "string",
                                        "description": "Café, Meia pensão, All inclusive"
                                    },
                                    "documentos_necessarios": {
                                        "type": "string",
                                        "description": "Texto multilinha"
                                    },
                                    "observacoes_pacote": {
                                        "type": "string",
                                        "description": "Texto multilinha"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/roteiro": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Listar dias do roteiro",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 10,
                                            "dia": 1,
                                            "titulo": "Chegada em Buenos Aires",
                                            "cidade": "Buenos Aires",
                                            "pernoite": "Hotel Madero",
                                            "regime": "Café da manhã",
                                            "atividades": [
                                                "Traslado",
                                                "City tour"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Adicionar dia ao roteiro",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 11,
                                        "dia": 2,
                                        "titulo": "Tour pela cidade"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "dia": {
                                        "type": "integer",
                                        "description": "Número sequencial do dia (1, 2, 3...)"
                                    },
                                    "titulo": {
                                        "type": "string",
                                        "description": "Max 255"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "pernoite": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "regime": {
                                        "type": "string",
                                        "description": "Café, almoço, jantar"
                                    },
                                    "atividades": {
                                        "type": "array",
                                        "description": "Lista de atividades do dia"
                                    },
                                    "imagem": {
                                        "type": "string",
                                        "description": "Path retornado por POST /roteiro/upload-imagem"
                                    }
                                },
                                "required": [
                                    "dia",
                                    "titulo"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/roteiro/{itinerarioId}": {
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar dia do roteiro",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "itinerarioId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "dia": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "titulo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "imagem": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "dia",
                                    "titulo"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover dia do roteiro",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "itinerarioId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Dia removido do roteiro."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/roteiro/reorder": {
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Reordenar dias",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Roteiro reordenado."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "items": {
                                        "type": "array",
                                        "description": "Lista de {id, dia} com a nova ordem"
                                    }
                                },
                                "required": [
                                    "items"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/roteiro/upload-imagem": {
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Upload de imagem (multipart)",
                "description": "Faz upload de uma imagem para usar em um dia do roteiro. Retorna `path` que deve ser informado no campo `imagem` ao criar ou atualizar o dia.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "path": "excursoes/123/roteiro/abcd1234.jpg"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "imagem": {
                                        "type": "string",
                                        "description": "multipart/form-data — jpg/jpeg/png/webp, max 5MB"
                                    }
                                },
                                "required": [
                                    "imagem"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/componentes": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Listar componentes (com dashboard)",
                "description": "Retorna lista de componentes + agregados (custo_total, preco_venda, margem, confirmados).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "componentes": [
                                            {
                                                "id": 25,
                                                "tipo": "hospedagem",
                                                "nome": "Hotel Madero - 5 noites",
                                                "custo_unitario": 350,
                                                "moeda_custo": "USD",
                                                "confirmacao_status": "pendente"
                                            }
                                        ],
                                        "dashboard": {
                                            "custo_total": 1820,
                                            "preco_venda": 2500,
                                            "margem": 680,
                                            "margem_percentual": 27.2,
                                            "confirmados": 0,
                                            "total": 1
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Adicionar componente",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 25
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": "hospedagem, refeicao, ingresso, transfer, voo, seguro, etc"
                                    },
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "fornecedor_nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "fornecedor_email": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "fornecedor_telefone": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "confirmacao_status": {
                                        "type": "string",
                                        "description": "pendente | confirmado | negado"
                                    },
                                    "confirmacao_codigo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "custo_unitario": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "custo_fixo": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "tipo_custo": {
                                        "type": "string",
                                        "description": "por_pessoa | por_quarto | fixo | por_diaria"
                                    },
                                    "moeda_custo": {
                                        "type": "string",
                                        "description": "BRL, USD, EUR... (default BRL)"
                                    },
                                    "taxa_cambio": {
                                        "type": "number",
                                        "description": "Se moeda != BRL"
                                    },
                                    "taxa_cambio_data": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "incluso": {
                                        "type": "boolean",
                                        "description": ""
                                    },
                                    "obrigatorio": {
                                        "type": "boolean",
                                        "description": ""
                                    },
                                    "valor_adicional": {
                                        "type": "number",
                                        "description": "Se não incluso"
                                    }
                                },
                                "required": [
                                    "tipo",
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/componentes/{componenteId}": {
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar componente",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "componenteId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "confirmacao_status": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "custo_unitario": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "tipo",
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover componente",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "componenteId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Componente removido."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/voos": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Listar voos",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Adicionar voo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 5
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": "ida | volta | conexao"
                                    },
                                    "cia_aerea": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "numero_voo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "aeroporto_origem": {
                                        "type": "string",
                                        "description": "IATA (3 letras)"
                                    },
                                    "aeroporto_destino": {
                                        "type": "string",
                                        "description": "IATA (3 letras)"
                                    },
                                    "data_voo": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "horario_partida": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "horario_chegada": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "classe": {
                                        "type": "string",
                                        "description": "economica | executiva | primeira"
                                    },
                                    "bagagem": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "tipo"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/voos/{vooId}": {
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar voo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vooId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "cia_aerea": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "numero_voo": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "tipo"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover voo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vooId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Voo removido."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/cruzeiro": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Obter cruzeiro",
                "description": "1:1 com a excursão. Retorna null se não houver.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": null
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Upsert do cruzeiro",
                "description": "Cria ou atualiza (uma única operação).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "companhia": {
                                        "type": "string",
                                        "description": "Ex: MSC, Costa, Royal Caribbean"
                                    },
                                    "navio": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "porto_embarque": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "porto_retorno": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "partida": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "chegada": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "itinerario": {
                                        "type": "string",
                                        "description": "Texto livre"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover cruzeiro",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cruzeiro removido."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/allotment": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Listar allotments",
                "description": "Quartos pré-reservados com deadline de liberação.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Criar allotment",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 9
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": "Ex: quarto, cabine, assento"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "quantidade_total": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "componente_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "deadline": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "custo_unitario": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "tipo",
                                    "descricao",
                                    "quantidade_total"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/allotment/{allotmentId}": {
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar allotment",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "allotmentId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "quantidade_total": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "ativo | esgotado | expirado | cancelado"
                                    }
                                },
                                "required": [
                                    "tipo",
                                    "descricao",
                                    "quantidade_total"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover allotment",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "allotmentId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Allotment removido."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/cotacoes": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Listar cotações",
                "description": "Disponível para qualquer excursão (não exige tipo_excursao=pacote_viagem).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Criar cotação",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 12
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "mensagem_personalizada": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "validade": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    }
                                },
                                "required": [
                                    "cliente_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/cotacoes/{cotacaoId}": {
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar cotação",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "cotacaoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "rascunho | enviada | visualizada | aceita | recusada | expirada"
                                    }
                                },
                                "required": [
                                    "cliente_id"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover cotação",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "cotacaoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cotacao removida."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/cotacoes/{cotacaoId}/opcoes": {
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Adicionar opção à cotação",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "cotacaoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 33
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Ex: Pacote Premium"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "valor_total": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "custo_total": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "componentes_inclusos": {
                                        "type": "array",
                                        "description": "Lista de strings com o que inclui"
                                    },
                                    "detalhes": {
                                        "type": "object",
                                        "description": "JSON livre"
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": "Marcar como recomendada"
                                    }
                                },
                                "required": [
                                    "nome",
                                    "valor_total"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/cotacoes/{cotacaoId}/opcoes/{opcaoId}": {
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar opção da cotação",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "cotacaoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "opcaoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "valor_total": {
                                        "type": "number",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "nome",
                                    "valor_total"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover opção da cotação",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "cotacaoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "opcaoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Opção removida."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/vouchers": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Listar vouchers de fornecedor",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Criar voucher",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 18
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": "Ex: ingresso, transfer, hospedagem"
                                    },
                                    "fornecedor_nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "fornecedor_contato": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "componente_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "codigo_reserva": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "data_servico": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "horario": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "detalhes": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "observacoes_internas": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "passageiros": {
                                        "type": "array",
                                        "description": "IDs de passageiros vinculados"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "pendente | confirmado | cancelado"
                                    }
                                },
                                "required": [
                                    "tipo",
                                    "fornecedor_nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/vouchers/{voucherId}": {
            "put": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Atualizar voucher",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "voucherId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "fornecedor_nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "tipo",
                                    "fornecedor_nome"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Remover voucher",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "voucherId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Voucher removido."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/pacote/dashboard-custo": {
            "get": {
                "tags": [
                    "Pacote de Viagem"
                ],
                "summary": "Dashboard agregado de custo",
                "description": "Custo unitário total, custo fixo total, custo total por pessoa, preço de venda, margem, receita estimada, lucro estimado e quebra por tipo de componente.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão (precisa ser tipo_excursao=pacote_viagem)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "custo_unitario_total": 1820,
                                        "custo_fixo_total": 500,
                                        "custo_total_por_pessoa": 1845,
                                        "preco_venda": 2500,
                                        "margem_por_pessoa": 655,
                                        "margem_percentual": 26.2,
                                        "passageiros_ativos": 20,
                                        "receita_estimada": 50000,
                                        "custo_estimado": 36900,
                                        "lucro_estimado": 13100,
                                        "componentes_confirmados": 5,
                                        "componentes_total": 8
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/custeio": {
            "get": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Painel completo de custeio",
                "description": "Retorna TUDO em uma chamada: custos fixos e variáveis listados, totais agregados, custo por pax, capacidade, passageiros vendidos, receita real, configuração de precificação, cenários por ocupação, ponto de equilíbrio (break-even em pax), rentabilidade real e comissões por vendedor.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "custos_fixos": [],
                                        "custos_variaveis": [],
                                        "variacoes": [],
                                        "pax_por_variacao": [],
                                        "total_fixo": 5000,
                                        "total_variavel": 150,
                                        "custo_por_pax": 250,
                                        "capacidade": 40,
                                        "passageiros_vendidos": 28,
                                        "receita_real": 11200,
                                        "precificacao": {
                                            "overhead_percentual": 10,
                                            "lucro_desejado_percentual": 20
                                        },
                                        "preco_sugerido": 380,
                                        "break_even_pax": 18,
                                        "cenarios": [],
                                        "rentabilidade": {
                                            "margem_real": 30.5,
                                            "lucro_real": 3416
                                        },
                                        "comissoes": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/custeio/custos": {
            "post": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Adicionar custo",
                "description": "Cria um custo da viagem (entra como `fin_conta_pagar` vinculada à excursão). `tipo_custo=fixo` é rateado entre todos os pax; `tipo_custo=variavel` é por pax (ou por variação se informar `excursao_variacao_id`).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Custo adicionado com sucesso!",
                                    "data": {
                                        "custo": {
                                            "id": 42
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "fornecedor": {
                                        "type": "string",
                                        "description": "Ex: Viação São Paulo, Hotel Madero"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição do custo"
                                    },
                                    "categoria_id": {
                                        "type": "integer",
                                        "description": "ID de fin_categorias"
                                    },
                                    "valor": {
                                        "type": "number",
                                        "description": "Min 0.01"
                                    },
                                    "tipo_custo": {
                                        "type": "string",
                                        "description": "fixo (rateado entre pax) | variavel (por pax)"
                                    },
                                    "excursao_variacao_id": {
                                        "type": "integer",
                                        "description": "Quando o custo variável aplica só a uma variação (ex: hospedagem camping vs alojamento)"
                                    },
                                    "data_vencimento": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "forma_pagamento": {
                                        "type": "string",
                                        "description": "dinheiro | pix | cartao_credito | cartao_debito | transferencia | boleto | cheque"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "desconto_crianca": {
                                        "type": "number",
                                        "description": "% de desconto pra criança (0-100)"
                                    },
                                    "desconto_idoso": {
                                        "type": "number",
                                        "description": "% de desconto pra idoso (0-100)"
                                    },
                                    "desconto_bebe": {
                                        "type": "number",
                                        "description": "% de desconto pra bebê (0-100)"
                                    }
                                },
                                "required": [
                                    "valor",
                                    "tipo_custo"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/custeio/custos/{custoId}": {
            "put": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Atualizar custo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "custoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do custo (FinContaPagar)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Custo atualizado com sucesso!"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "valor": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "tipo_custo": {
                                        "type": "string",
                                        "description": "fixo | variavel"
                                    },
                                    "fornecedor": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "categoria_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "data_vencimento": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "forma_pagamento": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "valor",
                                    "tipo_custo"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Remover custo",
                "description": "Soft delete. Custo deixa de impactar nos totais.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "custoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do custo (FinContaPagar)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Custo removido com sucesso!"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/custeio/custos/{custoId}/pagar": {
            "post": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Marcar custo como pago",
                "description": "Define `status=pago`, `valor_pago=valor`, `data_pagamento=now()`, `pago_por=usuário corrente`. Retorna 422 se já está pago.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "custoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do custo (FinContaPagar)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Custo marcado como pago!"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/custeio/custos/{custoId}/nao-pago": {
            "post": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Reverter pagamento do custo",
                "description": "Volta para `pendente` (ou `vencido` se passou da data). Retorna 422 se não estava pago.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "custoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do custo (FinContaPagar)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Pagamento revertido."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/custeio/precificacao": {
            "post": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Salvar configuração de precificação",
                "description": "Define a **composição de valores** que entra no cálculo do preço sugerido: overhead, lucro desejado, comissão de vendedor, taxas financeiras, ocupação estimada e mix de meios de pagamento. Persiste em `excursao_precificacao` (1:1 com excursão).",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Precificação salva com sucesso!",
                                    "data": {
                                        "precificacao": {
                                            "preco_sugerido": 380
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "overhead_percentual": {
                                        "type": "number",
                                        "description": "% de overhead (admin, marketing, infra)"
                                    },
                                    "lucro_desejado_percentual": {
                                        "type": "number",
                                        "description": "% de lucro alvo"
                                    },
                                    "comissao_vendedor_percentual": {
                                        "type": "number",
                                        "description": "% de comissão"
                                    },
                                    "comissao_base": {
                                        "type": "string",
                                        "description": "bruto | liquido | preco_venda | custo"
                                    },
                                    "taxa_financeira_media": {
                                        "type": "number",
                                        "description": "% médio das taxas de gateway"
                                    },
                                    "ocupacao_estimada": {
                                        "type": "integer",
                                        "description": "% de ocupação alvo (1-100)"
                                    },
                                    "passageiros_estimados": {
                                        "type": "integer",
                                        "description": "Nº absoluto de pax (alternativa a ocupacao_estimada)"
                                    },
                                    "mix_financeiro": {
                                        "type": "array",
                                        "description": "Array de {percentual, taxa} por meio de pagamento"
                                    },
                                    "taxas_financeiras": {
                                        "type": "array",
                                        "description": "Array de {percentual, taxa} alternativo"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/custeio/cenarios": {
            "post": {
                "tags": [
                    "Custeio da Viagem"
                ],
                "summary": "Calcular cenários ad-hoc por ocupação",
                "description": "Calcula cenários (margem, lucro, break-even) para um `preco_venda` arbitrário SEM persistir. Se `preco_venda` for omitido, usa o `preco_sugerido` da precificação salva. Retorna 422 se nem o preço foi informado nem há precificação salva.",
                "security": [
                    {
                        "bearerAuth": [
                            "excursoes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "cenarios": [
                                            {
                                                "ocupacao_pct": 50,
                                                "pax": 20,
                                                "receita": 7600,
                                                "custo": 6000,
                                                "lucro": 1600,
                                                "margem_pct": 21
                                            },
                                            {
                                                "ocupacao_pct": 100,
                                                "pax": 40,
                                                "receita": 15200,
                                                "custo": 11000,
                                                "lucro": 4200,
                                                "margem_pct": 27.6
                                            }
                                        ],
                                        "break_even_pax": 18,
                                        "capacidade": 40,
                                        "preco_venda": 380
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "preco_venda": {
                                        "type": "number",
                                        "description": "Preço de venda a testar. Se omitido, usa o preco_sugerido salvo."
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/passageiros": {
            "get": {
                "tags": [
                    "Passageiros"
                ],
                "summary": "Listar passageiros",
                "description": "Lista passageiros de uma excursão específica.",
                "security": [
                    {
                        "bearerAuth": [
                            "passageiros:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "pendente, confirmado, cancelado, embarcado",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por nome ou CPF",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens por página",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 1001,
                                            "excursao_id": 45,
                                            "cliente_id": 123,
                                            "comprador_id": 123,
                                            "preco_id": 77,
                                            "embarque_id": 12,
                                            "transporte_id": 9,
                                            "categoria_id": 1,
                                            "valor_cobrado": 1450,
                                            "status": "confirmado",
                                            "codigo_reserva": "VGABC12345",
                                            "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                            "assento": "A-10",
                                            "observacao": null,
                                            "cadastrado_via": "api",
                                            "cliente": {
                                                "id": 123,
                                                "nome": "Maria Silva Santos",
                                                "cpf": "12345678901",
                                                "telefone": "11999998888"
                                            },
                                            "preco": {
                                                "id": 77,
                                                "valor": 1450,
                                                "categoria_id": 1,
                                                "embarque_id": 12
                                            },
                                            "embarque": {
                                                "id": 12,
                                                "nome": "Terminal Tietê",
                                                "hora_embarque": "06:00"
                                            },
                                            "transporte": {
                                                "id": 9,
                                                "nome": "Ônibus 1",
                                                "tipo": "onibus_leito"
                                            },
                                            "categoria": {
                                                "id": 1,
                                                "nome": "Adulto"
                                            },
                                            "checkin_at": null,
                                            "created_at": "2024-01-20T11:30:00Z"
                                        }
                                    ],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 45
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Passageiros"
                ],
                "summary": "Adicionar passageiro",
                "description": "Adiciona um passageiro (cliente novo ou existente). Para múltiplos passageiros em uma order, prefira POST /reservas.",
                "security": [
                    {
                        "bearerAuth": [
                            "passageiros:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Passageiro adicionado com sucesso.",
                                    "data": {
                                        "id": 1001,
                                        "excursao_id": 45,
                                        "cliente_id": 123,
                                        "comprador_id": 123,
                                        "preco_id": 77,
                                        "embarque_id": 12,
                                        "transporte_id": 9,
                                        "categoria_id": 1,
                                        "valor_cobrado": 1450,
                                        "status": "confirmado",
                                        "codigo_reserva": "VGABC12345",
                                        "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                        "assento": "A-10",
                                        "observacao": null,
                                        "cadastrado_via": "api",
                                        "cliente": {
                                            "id": 123,
                                            "nome": "Maria Silva Santos",
                                            "cpf": "12345678901",
                                            "telefone": "11999998888"
                                        },
                                        "preco": {
                                            "id": 77,
                                            "valor": 1450,
                                            "categoria_id": 1,
                                            "embarque_id": 12
                                        },
                                        "embarque": {
                                            "id": 12,
                                            "nome": "Terminal Tietê",
                                            "hora_embarque": "06:00"
                                        },
                                        "transporte": {
                                            "id": 9,
                                            "nome": "Ônibus 1",
                                            "tipo": "onibus_leito"
                                        },
                                        "categoria": {
                                            "id": 1,
                                            "nome": "Adulto"
                                        },
                                        "checkin_at": null,
                                        "created_at": "2024-01-20T11:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "ID do cliente existente (ou enviar cliente inline)"
                                    },
                                    "cliente": {
                                        "type": "object",
                                        "description": "Dados do cliente inline: {nome*, cpf, email, telefone}"
                                    },
                                    "preco_id": {
                                        "type": "integer",
                                        "description": "ID do preço escolhido"
                                    },
                                    "categoria_id": {
                                        "type": "integer",
                                        "description": "ID da categoria (inferido do preço se omitido)"
                                    },
                                    "embarque_id": {
                                        "type": "integer",
                                        "description": "ID do ponto de embarque (opcional para pacote sem transporte)"
                                    },
                                    "transporte_id": {
                                        "type": "integer",
                                        "description": "ID do transporte (opcional para pacote sem transporte)"
                                    },
                                    "valor_cobrado": {
                                        "type": "number",
                                        "description": "Valor específico (default = valor do preço)"
                                    },
                                    "assento": {
                                        "type": "string",
                                        "description": "Identificador do assento (ex: A-10)"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": "Observações"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "pendente (default), confirmado"
                                    }
                                },
                                "required": [
                                    "preco_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/passageiros/{id}": {
            "get": {
                "tags": [
                    "Passageiros"
                ],
                "summary": "Detalhes do passageiro",
                "description": "Retorna passageiro com cliente, preço, embarque, transporte.",
                "security": [
                    {
                        "bearerAuth": [
                            "passageiros:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 1001,
                                        "excursao_id": 45,
                                        "cliente_id": 123,
                                        "comprador_id": 123,
                                        "preco_id": 77,
                                        "embarque_id": 12,
                                        "transporte_id": 9,
                                        "categoria_id": 1,
                                        "valor_cobrado": 1450,
                                        "status": "confirmado",
                                        "codigo_reserva": "VGABC12345",
                                        "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                        "assento": "A-10",
                                        "observacao": null,
                                        "cadastrado_via": "api",
                                        "cliente": {
                                            "id": 123,
                                            "nome": "Maria Silva Santos",
                                            "cpf": "12345678901",
                                            "telefone": "11999998888"
                                        },
                                        "preco": {
                                            "id": 77,
                                            "valor": 1450,
                                            "categoria_id": 1,
                                            "embarque_id": 12
                                        },
                                        "embarque": {
                                            "id": 12,
                                            "nome": "Terminal Tietê",
                                            "hora_embarque": "06:00"
                                        },
                                        "transporte": {
                                            "id": 9,
                                            "nome": "Ônibus 1",
                                            "tipo": "onibus_leito"
                                        },
                                        "categoria": {
                                            "id": 1,
                                            "nome": "Adulto"
                                        },
                                        "checkin_at": null,
                                        "created_at": "2024-01-20T11:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Passageiros"
                ],
                "summary": "Atualizar passageiro",
                "description": "Atualiza um passageiro (dados, embarque, assento, status).",
                "security": [
                    {
                        "bearerAuth": [
                            "passageiros:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Passageiro atualizado.",
                                    "data": {
                                        "id": 1001,
                                        "excursao_id": 45,
                                        "cliente_id": 123,
                                        "comprador_id": 123,
                                        "preco_id": 77,
                                        "embarque_id": 12,
                                        "transporte_id": 9,
                                        "categoria_id": 1,
                                        "valor_cobrado": 1450,
                                        "status": "confirmado",
                                        "codigo_reserva": "VGABC12345",
                                        "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                        "assento": "A-10",
                                        "observacao": null,
                                        "cadastrado_via": "api",
                                        "cliente": {
                                            "id": 123,
                                            "nome": "Maria Silva Santos",
                                            "cpf": "12345678901",
                                            "telefone": "11999998888"
                                        },
                                        "preco": {
                                            "id": 77,
                                            "valor": 1450,
                                            "categoria_id": 1,
                                            "embarque_id": 12
                                        },
                                        "embarque": {
                                            "id": 12,
                                            "nome": "Terminal Tietê",
                                            "hora_embarque": "06:00"
                                        },
                                        "transporte": {
                                            "id": 9,
                                            "nome": "Ônibus 1",
                                            "tipo": "onibus_leito"
                                        },
                                        "categoria": {
                                            "id": 1,
                                            "nome": "Adulto"
                                        },
                                        "checkin_at": null,
                                        "created_at": "2024-01-20T11:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "embarque_id": {
                                        "type": "integer",
                                        "description": "Trocar embarque"
                                    },
                                    "transporte_id": {
                                        "type": "integer",
                                        "description": "Trocar transporte"
                                    },
                                    "assento": {
                                        "type": "string",
                                        "description": "Novo assento"
                                    },
                                    "valor_cobrado": {
                                        "type": "number",
                                        "description": "Ajustar valor"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "pendente, confirmado, cancelado, embarcado"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": "Observações"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Passageiros"
                ],
                "summary": "Cancelar passageiro",
                "description": "Cancela (soft delete) o passageiro e libera a vaga.",
                "security": [
                    {
                        "bearerAuth": [
                            "passageiros:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Passageiro cancelado."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/passageiros/{id}/checkin": {
            "post": {
                "tags": [
                    "Passageiros"
                ],
                "summary": "Realizar check-in",
                "description": "Marca passageiro como embarcado (checkin).",
                "security": [
                    {
                        "bearerAuth": [
                            "checkin:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Check-in realizado.",
                                    "data": {
                                        "id": 1001,
                                        "excursao_id": 45,
                                        "cliente_id": 123,
                                        "comprador_id": 123,
                                        "preco_id": 77,
                                        "embarque_id": 12,
                                        "transporte_id": 9,
                                        "categoria_id": 1,
                                        "valor_cobrado": 1450,
                                        "status": "confirmado",
                                        "codigo_reserva": "VGABC12345",
                                        "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                        "assento": "A-10",
                                        "observacao": null,
                                        "cadastrado_via": "api",
                                        "cliente": {
                                            "id": 123,
                                            "nome": "Maria Silva Santos",
                                            "cpf": "12345678901",
                                            "telefone": "11999998888"
                                        },
                                        "preco": {
                                            "id": 77,
                                            "valor": 1450,
                                            "categoria_id": 1,
                                            "embarque_id": 12
                                        },
                                        "embarque": {
                                            "id": 12,
                                            "nome": "Terminal Tietê",
                                            "hora_embarque": "06:00"
                                        },
                                        "transporte": {
                                            "id": 9,
                                            "nome": "Ônibus 1",
                                            "tipo": "onibus_leito"
                                        },
                                        "categoria": {
                                            "id": 1,
                                            "nome": "Adulto"
                                        },
                                        "checkin_at": null,
                                        "created_at": "2024-01-20T11:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude do ponto de check-in"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": "Observação"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/passageiros/{id}/cartao-embarque": {
            "get": {
                "tags": [
                    "Passageiros"
                ],
                "summary": "Cartão de embarque (PDF, base64 ou link)",
                "description": "Retorna o cartão de embarque do passageiro. O parâmetro `format` define o formato: `pdf` (default, stream binário application/pdf), `base64` (JSON com PDF em base64) ou `link` (JSON com URL pública assinada via token). O parâmetro `grupo` aplica-se a TODOS os formatos: quando true (ou auto-detectado), retorna o cartão consolidado de todo o grupo (titular + dependentes), uma página por passageiro no PDF.",
                "security": [
                    {
                        "bearerAuth": [
                            "passageiros:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "required": false,
                        "description": "Formato de retorno: pdf | base64 | link (default: pdf)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "grupo",
                        "in": "query",
                        "required": false,
                        "description": "Se true, retorna o cartão de embarque do grupo todo (titular + dependentes). Default: auto — true quando o passageiro tem dependentes ativos, false para individual. Vale para todos os formatos (pdf/base64/link).",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "filename": "cartao-embarque-ABCD1234.pdf",
                                        "content_type": "application/pdf",
                                        "content_base64": "JVBERi0xLjQK...",
                                        "size_bytes": 142536
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/clientes": {
            "get": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Listar clientes",
                "description": "Lista paginada de clientes com filtros.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Página",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens (max 100)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por nome, email, CPF, celular ou telefone. Termos com 5+ dígitos cruzam com CPF/celular/telefone normalizados.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "email",
                        "in": "query",
                        "required": false,
                        "description": "E-mail exato",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cpf",
                        "in": "query",
                        "required": false,
                        "description": "CPF (com ou sem formatação)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "celular",
                        "in": "query",
                        "required": false,
                        "description": "Celular/WhatsApp. Aceita com/sem DDI 55, com/sem 9, com/sem máscara. Compara últimos 10 dígitos.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "whatsapp",
                        "in": "query",
                        "required": false,
                        "description": "Alias de celular",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "telefone",
                        "in": "query",
                        "required": false,
                        "description": "Filtra também pela coluna telefone (fixo). Mesma normalização.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por ativo/inativo",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 123,
                                            "nome": "Maria Silva Santos",
                                            "email": "maria@example.com",
                                            "cpf": "12345678901",
                                            "rg": "12.345.678-9",
                                            "passaporte": null,
                                            "nacionalidade": "Brasileira",
                                            "documento_estrangeiro": null,
                                            "documento_estrangeiro_tipo": null,
                                            "documento_estrangeiro_emissor": null,
                                            "documento_estrangeiro_emissao": null,
                                            "data_nascimento": "1985-03-15",
                                            "telefone": "1133334444",
                                            "celular": "11999998888",
                                            "instagram": "@maria.silva",
                                            "cep": "01310-100",
                                            "endereco": "Av. Paulista",
                                            "numero": "1000",
                                            "complemento": "Apto 52",
                                            "bairro": "Bela Vista",
                                            "cidade": "São Paulo",
                                            "estado": "SP",
                                            "contato_emergencia_nome": "João Silva",
                                            "contato_emergencia_parentesco": "Cônjuge",
                                            "contato_emergencia_telefone": "11988887777",
                                            "avatar_url": null,
                                            "observacoes": null,
                                            "ativo": true,
                                            "origem_cadastro": "api",
                                            "campos_personalizados": {
                                                "profissao": "Engenheiro",
                                                "tamanho_camiseta": "M"
                                            },
                                            "created_at": "2024-01-10T14:30:00Z",
                                            "updated_at": "2024-02-05T09:15:00Z"
                                        }
                                    ],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 1250
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Criar cliente",
                "description": "Cria um cliente. origem_cadastro é gravado automaticamente como \"api\". Valida unicidade de CPF e email (retorna 409 em duplicata). A resposta inclui um auto_login_url (magic link de 30 min, one-time use) pronto para redirecionar o cliente já logado no portal.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cliente criado com sucesso.",
                                    "data": {
                                        "id": 123,
                                        "nome": "Maria Silva Santos",
                                        "email": "maria@example.com",
                                        "cpf": "12345678901",
                                        "rg": "12.345.678-9",
                                        "passaporte": null,
                                        "nacionalidade": "Brasileira",
                                        "documento_estrangeiro": null,
                                        "documento_estrangeiro_tipo": null,
                                        "documento_estrangeiro_emissor": null,
                                        "documento_estrangeiro_emissao": null,
                                        "data_nascimento": "1985-03-15",
                                        "telefone": "1133334444",
                                        "celular": "11999998888",
                                        "instagram": "@maria.silva",
                                        "cep": "01310-100",
                                        "endereco": "Av. Paulista",
                                        "numero": "1000",
                                        "complemento": "Apto 52",
                                        "bairro": "Bela Vista",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_emergencia_nome": "João Silva",
                                        "contato_emergencia_parentesco": "Cônjuge",
                                        "contato_emergencia_telefone": "11988887777",
                                        "avatar_url": null,
                                        "observacoes": null,
                                        "ativo": true,
                                        "origem_cadastro": "api",
                                        "campos_personalizados": {
                                            "profissao": "Engenheiro",
                                            "tamanho_camiseta": "M"
                                        },
                                        "created_at": "2024-01-10T14:30:00Z",
                                        "updated_at": "2024-02-05T09:15:00Z",
                                        "auto_login_url": "https://seu-tenant.viagilize.com.br/auth/magic/abc123...",
                                        "auto_login_expires_at": "2026-04-21T22:15:00+00:00",
                                        "auto_login_single_use": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome completo (required em POST)"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail (único)"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "CPF (apenas dígitos ou formatado, será normalizado)"
                                    },
                                    "rg": {
                                        "type": "string",
                                        "description": "RG"
                                    },
                                    "passaporte": {
                                        "type": "string",
                                        "description": "Número do passaporte"
                                    },
                                    "nacionalidade": {
                                        "type": "string",
                                        "description": "Nacionalidade"
                                    },
                                    "documento_estrangeiro": {
                                        "type": "string",
                                        "description": "Documento estrangeiro (para não-brasileiros)"
                                    },
                                    "documento_estrangeiro_tipo": {
                                        "type": "string",
                                        "description": "Tipo do documento estrangeiro"
                                    },
                                    "documento_estrangeiro_emissor": {
                                        "type": "string",
                                        "description": "Órgão emissor"
                                    },
                                    "documento_estrangeiro_emissao": {
                                        "type": "string",
                                        "description": "Data de emissão (Y-m-d)"
                                    },
                                    "data_nascimento": {
                                        "type": "string",
                                        "description": "Data de nascimento (Y-m-d)"
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone fixo"
                                    },
                                    "celular": {
                                        "type": "string",
                                        "description": "Celular/WhatsApp"
                                    },
                                    "instagram": {
                                        "type": "string",
                                        "description": "@usuario do Instagram"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Logradouro"
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Número"
                                    },
                                    "complemento": {
                                        "type": "string",
                                        "description": "Complemento"
                                    },
                                    "bairro": {
                                        "type": "string",
                                        "description": "Bairro"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF (2 letras)"
                                    },
                                    "contato_emergencia_nome": {
                                        "type": "string",
                                        "description": "Nome do contato de emergência"
                                    },
                                    "contato_emergencia_parentesco": {
                                        "type": "string",
                                        "description": "Parentesco do contato"
                                    },
                                    "contato_emergencia_telefone": {
                                        "type": "string",
                                        "description": "Telefone do contato"
                                    },
                                    "avatar_url": {
                                        "type": "string",
                                        "description": "URL da foto"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Cliente ativo (default true)"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações livres"
                                    },
                                    "campos_personalizados": {
                                        "type": "object",
                                        "description": "Campos personalizados de cliente. Objeto { field_key: valor }. Os field_keys variam por empresa (veja os campos ativos em Configurações > Formulários > Clientes). Em campos de seleção aceita o value da opção OU o rótulo (mapeado para o value); multi-seleção por lista separada por vírgula. field_key inexistente ou valor de seleção inválido retornam 422 com as opções válidas."
                                    }
                                },
                                "required": [
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/clientes/cpf": {
            "get": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Buscar cliente por CPF",
                "description": "Busca exata por CPF (11 dígitos).",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "cpf",
                        "in": "query",
                        "required": true,
                        "description": "CPF (com ou sem formatação)",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 123,
                                        "nome": "Maria Silva Santos",
                                        "email": "maria@example.com",
                                        "cpf": "12345678901",
                                        "rg": "12.345.678-9",
                                        "passaporte": null,
                                        "nacionalidade": "Brasileira",
                                        "documento_estrangeiro": null,
                                        "documento_estrangeiro_tipo": null,
                                        "documento_estrangeiro_emissor": null,
                                        "documento_estrangeiro_emissao": null,
                                        "data_nascimento": "1985-03-15",
                                        "telefone": "1133334444",
                                        "celular": "11999998888",
                                        "instagram": "@maria.silva",
                                        "cep": "01310-100",
                                        "endereco": "Av. Paulista",
                                        "numero": "1000",
                                        "complemento": "Apto 52",
                                        "bairro": "Bela Vista",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_emergencia_nome": "João Silva",
                                        "contato_emergencia_parentesco": "Cônjuge",
                                        "contato_emergencia_telefone": "11988887777",
                                        "avatar_url": null,
                                        "observacoes": null,
                                        "ativo": true,
                                        "origem_cadastro": "api",
                                        "campos_personalizados": {
                                            "profissao": "Engenheiro",
                                            "tamanho_camiseta": "M"
                                        },
                                        "created_at": "2024-01-10T14:30:00Z",
                                        "updated_at": "2024-02-05T09:15:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/clientes/celular": {
            "get": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Buscar cliente por celular/WhatsApp",
                "description": "Busca cliente pelo telefone com normalização tolerante a formato (DDI 55, 9 mobile, máscara). Útil para chatbots identificarem cliente recorrente a partir do número do WhatsApp.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "celular",
                        "in": "query",
                        "required": false,
                        "description": "Aceita whatsapp= ou telefone= como alias. Ex: \"85999281920\", \"(85) 99928-1920\", \"+5585999281920\"",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "whatsapp",
                        "in": "query",
                        "required": false,
                        "description": "Alias de celular",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "telefone",
                        "in": "query",
                        "required": false,
                        "description": "Alias de celular",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 123,
                                        "nome": "Maria Silva Santos",
                                        "email": "maria@example.com",
                                        "cpf": "12345678901",
                                        "rg": "12.345.678-9",
                                        "passaporte": null,
                                        "nacionalidade": "Brasileira",
                                        "documento_estrangeiro": null,
                                        "documento_estrangeiro_tipo": null,
                                        "documento_estrangeiro_emissor": null,
                                        "documento_estrangeiro_emissao": null,
                                        "data_nascimento": "1985-03-15",
                                        "telefone": "1133334444",
                                        "celular": "11999998888",
                                        "instagram": "@maria.silva",
                                        "cep": "01310-100",
                                        "endereco": "Av. Paulista",
                                        "numero": "1000",
                                        "complemento": "Apto 52",
                                        "bairro": "Bela Vista",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_emergencia_nome": "João Silva",
                                        "contato_emergencia_parentesco": "Cônjuge",
                                        "contato_emergencia_telefone": "11988887777",
                                        "avatar_url": null,
                                        "observacoes": null,
                                        "ativo": true,
                                        "origem_cadastro": "api",
                                        "campos_personalizados": {
                                            "profissao": "Engenheiro",
                                            "tamanho_camiseta": "M"
                                        },
                                        "created_at": "2024-01-10T14:30:00Z",
                                        "updated_at": "2024-02-05T09:15:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/clientes/{id}": {
            "get": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Detalhes do cliente",
                "description": "Retorna o cliente. Use include_dependentes=true para trazer os dependentes.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "include_dependentes",
                        "in": "query",
                        "required": false,
                        "description": "Se true, inclui array dependentes na resposta",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 123,
                                        "nome": "Maria Silva Santos",
                                        "email": "maria@example.com",
                                        "cpf": "12345678901",
                                        "rg": "12.345.678-9",
                                        "passaporte": null,
                                        "nacionalidade": "Brasileira",
                                        "documento_estrangeiro": null,
                                        "documento_estrangeiro_tipo": null,
                                        "documento_estrangeiro_emissor": null,
                                        "documento_estrangeiro_emissao": null,
                                        "data_nascimento": "1985-03-15",
                                        "telefone": "1133334444",
                                        "celular": "11999998888",
                                        "instagram": "@maria.silva",
                                        "cep": "01310-100",
                                        "endereco": "Av. Paulista",
                                        "numero": "1000",
                                        "complemento": "Apto 52",
                                        "bairro": "Bela Vista",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_emergencia_nome": "João Silva",
                                        "contato_emergencia_parentesco": "Cônjuge",
                                        "contato_emergencia_telefone": "11988887777",
                                        "avatar_url": null,
                                        "observacoes": null,
                                        "ativo": true,
                                        "origem_cadastro": "api",
                                        "campos_personalizados": {
                                            "profissao": "Engenheiro",
                                            "tamanho_camiseta": "M"
                                        },
                                        "created_at": "2024-01-10T14:30:00Z",
                                        "updated_at": "2024-02-05T09:15:00Z",
                                        "dependentes": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Atualizar cliente",
                "description": "Atualiza parcialmente um cliente. Todos os campos são opcionais.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cliente atualizado com sucesso.",
                                    "data": {
                                        "id": 123,
                                        "nome": "Maria Silva Santos",
                                        "email": "maria@example.com",
                                        "cpf": "12345678901",
                                        "rg": "12.345.678-9",
                                        "passaporte": null,
                                        "nacionalidade": "Brasileira",
                                        "documento_estrangeiro": null,
                                        "documento_estrangeiro_tipo": null,
                                        "documento_estrangeiro_emissor": null,
                                        "documento_estrangeiro_emissao": null,
                                        "data_nascimento": "1985-03-15",
                                        "telefone": "1133334444",
                                        "celular": "11999998888",
                                        "instagram": "@maria.silva",
                                        "cep": "01310-100",
                                        "endereco": "Av. Paulista",
                                        "numero": "1000",
                                        "complemento": "Apto 52",
                                        "bairro": "Bela Vista",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_emergencia_nome": "João Silva",
                                        "contato_emergencia_parentesco": "Cônjuge",
                                        "contato_emergencia_telefone": "11988887777",
                                        "avatar_url": null,
                                        "observacoes": null,
                                        "ativo": true,
                                        "origem_cadastro": "api",
                                        "campos_personalizados": {
                                            "profissao": "Engenheiro",
                                            "tamanho_camiseta": "M"
                                        },
                                        "created_at": "2024-01-10T14:30:00Z",
                                        "updated_at": "2024-02-05T09:15:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome completo (required em POST)"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail (único)"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "CPF (apenas dígitos ou formatado, será normalizado)"
                                    },
                                    "rg": {
                                        "type": "string",
                                        "description": "RG"
                                    },
                                    "passaporte": {
                                        "type": "string",
                                        "description": "Número do passaporte"
                                    },
                                    "nacionalidade": {
                                        "type": "string",
                                        "description": "Nacionalidade"
                                    },
                                    "documento_estrangeiro": {
                                        "type": "string",
                                        "description": "Documento estrangeiro (para não-brasileiros)"
                                    },
                                    "documento_estrangeiro_tipo": {
                                        "type": "string",
                                        "description": "Tipo do documento estrangeiro"
                                    },
                                    "documento_estrangeiro_emissor": {
                                        "type": "string",
                                        "description": "Órgão emissor"
                                    },
                                    "documento_estrangeiro_emissao": {
                                        "type": "string",
                                        "description": "Data de emissão (Y-m-d)"
                                    },
                                    "data_nascimento": {
                                        "type": "string",
                                        "description": "Data de nascimento (Y-m-d)"
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone fixo"
                                    },
                                    "celular": {
                                        "type": "string",
                                        "description": "Celular/WhatsApp"
                                    },
                                    "instagram": {
                                        "type": "string",
                                        "description": "@usuario do Instagram"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Logradouro"
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Número"
                                    },
                                    "complemento": {
                                        "type": "string",
                                        "description": "Complemento"
                                    },
                                    "bairro": {
                                        "type": "string",
                                        "description": "Bairro"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF (2 letras)"
                                    },
                                    "contato_emergencia_nome": {
                                        "type": "string",
                                        "description": "Nome do contato de emergência"
                                    },
                                    "contato_emergencia_parentesco": {
                                        "type": "string",
                                        "description": "Parentesco do contato"
                                    },
                                    "contato_emergencia_telefone": {
                                        "type": "string",
                                        "description": "Telefone do contato"
                                    },
                                    "avatar_url": {
                                        "type": "string",
                                        "description": "URL da foto"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Cliente ativo (default true)"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações livres"
                                    },
                                    "campos_personalizados": {
                                        "type": "object",
                                        "description": "Campos personalizados de cliente. Objeto { field_key: valor }. Os field_keys variam por empresa (veja os campos ativos em Configurações > Formulários > Clientes). Em campos de seleção aceita o value da opção OU o rótulo (mapeado para o value); multi-seleção por lista separada por vírgula. field_key inexistente ou valor de seleção inválido retornam 422 com as opções válidas."
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Excluir cliente",
                "description": "Remove o cliente (soft delete).",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cliente excluído com sucesso."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/clientes/{id}/reservas": {
            "get": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Pedidos do cliente",
                "description": "Lista paginada dos pedidos (Orders) onde o cliente é comprador. Retorna o pedido completo com codigo, valor_total, status e passageiros aninhados (incluindo vagas pendentes com cadastrado_via=convite_pendente).",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Filtro CSV (ex: \"pendente,confirmado\")",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "excursao_id",
                        "in": "query",
                        "required": false,
                        "description": "Pedidos contendo passageiros desta excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Modificados a partir de (ISO 8601). Sync incremental.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens (max 100)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 501,
                                            "codigo": "VG-ABC12345",
                                            "valor_total": 2900,
                                            "valor_pago": 0,
                                            "valor_pendente": 2900,
                                            "status": "pendente",
                                            "passageiros": [
                                                {
                                                    "id": 1001,
                                                    "nome": "Maria Silva",
                                                    "cadastrado_via": "api",
                                                    "valor_cobrado": 1450
                                                },
                                                {
                                                    "id": 1002,
                                                    "nome": "Vaga 2",
                                                    "cadastrado_via": "convite_pendente",
                                                    "valor_cobrado": 1450
                                                }
                                            ]
                                        }
                                    ],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 5
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/clientes/{id}/auto-login": {
            "post": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Gerar link de auto-login (magic link)",
                "description": "Gera um novo token de auto-login para um cliente existente. O token é válido por 30 minutos, one-time use (invalida após primeiro clique) e invalida qualquer token anterior. Use para SSO: parceiro envia o URL por WhatsApp/email e o cliente cai já logado em /minha-conta.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Link de login automático gerado.",
                                    "data": {
                                        "cliente_id": 86,
                                        "auto_login_url": "https://seu-tenant.viagilize.com.br/auth/magic/abc123...",
                                        "auto_login_expires_at": "2026-04-21T22:15:00+00:00",
                                        "auto_login_single_use": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Revogar token de auto-login",
                "description": "Invalida o token atual do cliente (equivalente a \"logout forçado\" dos links pendentes). Use em caso de token comprometido.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Token de auto-login revogado."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/clientes/{id}/dependentes": {
            "get": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Listar dependentes",
                "description": "Lista os dependentes (filhos, cônjuges, etc) do cliente.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 301,
                                            "cliente_id": 123,
                                            "nome": "Lucas Silva",
                                            "cpf": "98765432100",
                                            "data_nascimento": "2012-06-20",
                                            "parentesco": "filho",
                                            "created_at": "2024-03-12T10:00:00Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Criar dependente",
                "description": "Cria um dependente vinculado ao cliente.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Dependente criado com sucesso.",
                                    "data": {
                                        "id": 301,
                                        "cliente_id": 123,
                                        "nome": "Lucas Silva",
                                        "parentesco": "filho"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome completo"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "CPF"
                                    },
                                    "rg": {
                                        "type": "string",
                                        "description": "RG"
                                    },
                                    "passaporte": {
                                        "type": "string",
                                        "description": "Passaporte"
                                    },
                                    "nacionalidade": {
                                        "type": "string",
                                        "description": "Nacionalidade"
                                    },
                                    "documento_estrangeiro": {
                                        "type": "string",
                                        "description": "Documento estrangeiro"
                                    },
                                    "documento_estrangeiro_tipo": {
                                        "type": "string",
                                        "description": "Tipo"
                                    },
                                    "documento_estrangeiro_emissor": {
                                        "type": "string",
                                        "description": "Emissor"
                                    },
                                    "documento_estrangeiro_emissao": {
                                        "type": "string",
                                        "description": "Emissão"
                                    },
                                    "data_nascimento": {
                                        "type": "string",
                                        "description": "Nascimento"
                                    },
                                    "parentesco": {
                                        "type": "string",
                                        "description": "filho, cônjuge, pai, mãe..."
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    }
                                },
                                "required": [
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/clientes/{id}/dependentes/{dependenteId}": {
            "put": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Atualizar dependente",
                "description": "Atualiza um dependente. Todos os campos são opcionais.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "dependenteId",
                        "in": "path",
                        "required": true,
                        "description": "ID do dependente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Dependente atualizado com sucesso.",
                                    "data": {
                                        "id": 301,
                                        "nome": "Lucas Silva Atualizado"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome completo"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "CPF"
                                    },
                                    "rg": {
                                        "type": "string",
                                        "description": "RG"
                                    },
                                    "passaporte": {
                                        "type": "string",
                                        "description": "Passaporte"
                                    },
                                    "nacionalidade": {
                                        "type": "string",
                                        "description": "Nacionalidade"
                                    },
                                    "documento_estrangeiro": {
                                        "type": "string",
                                        "description": "Documento estrangeiro"
                                    },
                                    "documento_estrangeiro_tipo": {
                                        "type": "string",
                                        "description": "Tipo"
                                    },
                                    "documento_estrangeiro_emissor": {
                                        "type": "string",
                                        "description": "Emissor"
                                    },
                                    "documento_estrangeiro_emissao": {
                                        "type": "string",
                                        "description": "Emissão"
                                    },
                                    "data_nascimento": {
                                        "type": "string",
                                        "description": "Nascimento"
                                    },
                                    "parentesco": {
                                        "type": "string",
                                        "description": "filho, cônjuge, pai, mãe..."
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Clientes"
                ],
                "summary": "Excluir dependente",
                "description": "Remove o dependente.",
                "security": [
                    {
                        "bearerAuth": [
                            "clientes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cliente",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "dependenteId",
                        "in": "path",
                        "required": true,
                        "description": "ID do dependente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Dependente excluído com sucesso."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/reservas": {
            "get": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Listar reservas",
                "description": "Lista paginada de orders/reservas com filtros.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Página",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens (max 100)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "pendente, parcial, pago, cancelado, reembolsado",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cliente_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por comprador",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "excursao_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "data_de",
                        "in": "query",
                        "required": false,
                        "description": "Criadas a partir de (Y-m-d)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_ate",
                        "in": "query",
                        "required": false,
                        "description": "Criadas até (Y-m-d)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Modificadas a partir de (ISO 8601). Útil para sync incremental.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por código da order, nome ou email do comprador",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 501,
                                            "codigo": "VG-ABC12345",
                                            "comprador_id": 123,
                                            "status": "pendente",
                                            "valor_original": 2900,
                                            "valor_total": 2900,
                                            "valor_pago": 0,
                                            "valor_pendente": 2900,
                                            "pagamento_expira_em": "2026-04-26T18:30:42-03:00",
                                            "forma_pagamento": "pix",
                                            "parcelas": 1,
                                            "origem": "api",
                                            "gateway_preference_id": null,
                                            "comprador": {
                                                "id": 123,
                                                "nome": "Maria Silva Santos",
                                                "email": "maria@example.com",
                                                "cpf": "12345678901"
                                            },
                                            "passageiros": [
                                                {
                                                    "id": 1001,
                                                    "excursao_id": 45,
                                                    "cliente_id": 123,
                                                    "preco_id": 77,
                                                    "embarque_id": 12,
                                                    "transporte_id": 9,
                                                    "categoria_id": 1,
                                                    "valor_cobrado": 1450,
                                                    "status": "pendente",
                                                    "codigo_reserva": "VGABC12345",
                                                    "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                                    "excursao": {
                                                        "id": 45,
                                                        "nome": "Gramado - Natal Luz 2025"
                                                    }
                                                },
                                                {
                                                    "id": 1002,
                                                    "excursao_id": 45,
                                                    "cliente_id": 124,
                                                    "preco_id": 77,
                                                    "valor_cobrado": 1450,
                                                    "status": "pendente",
                                                    "codigo_reserva": "VGDEF67890"
                                                }
                                            ],
                                            "payments": [],
                                            "created_at": "2024-10-15T11:30:00Z"
                                        }
                                    ],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 32
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Criar reserva",
                "description": "Cria uma order com um ou mais passageiros em transação. Aceita cliente_id existente ou objeto cliente inline (auto-cria por CPF/email). Se gerar_link_pagamento=true, retorna também `payment_url` do gateway ativo. Se a geração falhar (sem gateway, excursão sem preço, etc), a reserva ainda é criada e a resposta inclui `payment_link_error: { code, message }` em vez de `payment_url`.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Reserva criada com sucesso.",
                                    "data": {
                                        "id": 501,
                                        "codigo": "VG-ABC12345",
                                        "comprador_id": 123,
                                        "status": "pendente",
                                        "valor_original": 2900,
                                        "valor_total": 2900,
                                        "valor_pago": 0,
                                        "valor_pendente": 2900,
                                        "pagamento_expira_em": "2026-04-26T18:30:42-03:00",
                                        "forma_pagamento": "pix",
                                        "parcelas": 1,
                                        "origem": "api",
                                        "gateway_preference_id": null,
                                        "comprador": {
                                            "id": 123,
                                            "nome": "Maria Silva Santos",
                                            "email": "maria@example.com",
                                            "cpf": "12345678901"
                                        },
                                        "passageiros": [
                                            {
                                                "id": 1001,
                                                "excursao_id": 45,
                                                "cliente_id": 123,
                                                "preco_id": 77,
                                                "embarque_id": 12,
                                                "transporte_id": 9,
                                                "categoria_id": 1,
                                                "valor_cobrado": 1450,
                                                "status": "pendente",
                                                "codigo_reserva": "VGABC12345",
                                                "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                                "excursao": {
                                                    "id": 45,
                                                    "nome": "Gramado - Natal Luz 2025"
                                                }
                                            },
                                            {
                                                "id": 1002,
                                                "excursao_id": 45,
                                                "cliente_id": 124,
                                                "preco_id": 77,
                                                "valor_cobrado": 1450,
                                                "status": "pendente",
                                                "codigo_reserva": "VGDEF67890"
                                            }
                                        ],
                                        "payments": [],
                                        "created_at": "2024-10-15T11:30:00Z",
                                        "payment_url": "https://mpago.la/abc123",
                                        "payment_gateway": "Mercado Pago"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "excursao_id": {
                                        "type": "integer",
                                        "description": "ID da excursão/pacote"
                                    },
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "ID do comprador (ou enviar cliente inline)"
                                    },
                                    "cliente": {
                                        "type": "object",
                                        "description": "Dados do comprador inline: {nome*, email, cpf, telefone, celular, cep, endereco, numero, bairro, cidade, estado, forcar_novo?}. Dedupe LGPD: CPF first, e-mail só reusa se cliente existente nao tiver CPF. Use forcar_novo=true para pular dedupe."
                                    },
                                    "passageiros": {
                                        "type": "array",
                                        "description": "Lista (1-20): {cliente_id|cliente|pendente, preco_id*, categoria_id?, embarque_id?, transporte_id?, valor_cobrado?, observacao?}. Use pendente:true (sem cliente_id/cliente) pra criar vaga aguardando dados — o comprador preenche depois (portal /minha-conta/convites, API POST .../preencher, ou link público de convite retornado)."
                                    },
                                    "forma_pagamento": {
                                        "type": "string",
                                        "description": "pix, cartao, boleto, dinheiro, transferencia"
                                    },
                                    "parcelas": {
                                        "type": "integer",
                                        "description": "Número de parcelas (1-24)"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações livres"
                                    },
                                    "gerar_link_pagamento": {
                                        "type": "boolean",
                                        "description": "Se true, retorna payment_url junto"
                                    }
                                },
                                "required": [
                                    "excursao_id",
                                    "passageiros"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/reservas/{id}": {
            "get": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Detalhes da reserva",
                "description": "Reserva completa com passageiros, preços, embarques, transportes, pagamentos e financeiro. Inclui também `total_pendentes` (vagas aguardando preenchimento), `passageiros_completos` e `passageiros_total` — use pra decidir liberação de cartão de embarque sem precisar chamar /passageiros-pendentes.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva (order)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 501,
                                        "codigo": "VG-ABC12345",
                                        "comprador_id": 123,
                                        "status": "pendente",
                                        "valor_original": 2900,
                                        "valor_total": 2900,
                                        "valor_pago": 0,
                                        "valor_pendente": 2900,
                                        "pagamento_expira_em": "2026-04-26T18:30:42-03:00",
                                        "forma_pagamento": "pix",
                                        "parcelas": 1,
                                        "origem": "api",
                                        "gateway_preference_id": null,
                                        "comprador": {
                                            "id": 123,
                                            "nome": "Maria Silva Santos",
                                            "email": "maria@example.com",
                                            "cpf": "12345678901"
                                        },
                                        "passageiros": [
                                            {
                                                "id": 1001,
                                                "excursao_id": 45,
                                                "cliente_id": 123,
                                                "preco_id": 77,
                                                "embarque_id": 12,
                                                "transporte_id": 9,
                                                "categoria_id": 1,
                                                "valor_cobrado": 1450,
                                                "status": "pendente",
                                                "codigo_reserva": "VGABC12345",
                                                "qr_code": "550e8400-e29b-41d4-a716-446655440000",
                                                "excursao": {
                                                    "id": 45,
                                                    "nome": "Gramado - Natal Luz 2025"
                                                }
                                            },
                                            {
                                                "id": 1002,
                                                "excursao_id": 45,
                                                "cliente_id": 124,
                                                "preco_id": 77,
                                                "valor_cobrado": 1450,
                                                "status": "pendente",
                                                "codigo_reserva": "VGDEF67890"
                                            }
                                        ],
                                        "payments": [],
                                        "created_at": "2024-10-15T11:30:00Z",
                                        "total_pendentes": 0,
                                        "passageiros_completos": 3,
                                        "passageiros_total": 3
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Remover reserva (hard delete)",
                "description": "Remove permanentemente uma reserva e todos os passageiros, financeiros, pagamentos e vagas pendentes vinculados. Só funciona com status=cancelado — use POST /reservas/{id}/cancel primeiro para reservas ativas.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Reserva removida permanentemente.",
                                    "data": {
                                        "codigo": "A8CA1475"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/reservas/{id}/payment-link": {
            "post": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Gerar link de pagamento",
                "description": "Gera uma URL de pagamento no gateway ativo do tenant (Mercado Pago, Asaas, Pagar.me, Infinite Pay, PagSeguro, ValePay). Requer que o tenant tenha ao menos um gateway configurado e habilitado.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "url": "https://mpago.la/abc123",
                                        "gateway": "Mercado Pago",
                                        "valor": 2900,
                                        "order_id": 501
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "valor": {
                                        "type": "number",
                                        "description": "Valor a cobrar (default = valor_pendente da reserva)"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/reservas/{id}/payments": {
            "post": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Registrar pagamento manual",
                "description": "Registra um pagamento manual (dinheiro, transferência, PIX confirmado fora do gateway, etc). Cria OrderPayment, propaga para o financeiro de cada passageiro proporcionalmente ao valor cobrado, confirma passageiros automaticamente se o valor total for atingido e envia e-mail de confirmação.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Pagamento registrado com sucesso.",
                                    "data": {
                                        "payment": {
                                            "id": 42,
                                            "order_id": 501,
                                            "valor": 1450,
                                            "forma_pagamento": "pix",
                                            "status": "aprovado",
                                            "pago_em": "2024-10-25T10:15:00Z"
                                        },
                                        "order": {
                                            "id": 501,
                                            "codigo": "VG-ABC12345",
                                            "valor_total": 2900,
                                            "valor_pago": 1450,
                                            "valor_pendente": 1450,
                                            "status": "parcial"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "valor": {
                                        "type": "number",
                                        "description": "Valor pago (não pode exceder valor_pendente)"
                                    },
                                    "forma_pagamento": {
                                        "type": "string",
                                        "description": "pix, cartao, boleto, dinheiro, transferencia, cheque"
                                    },
                                    "gateway": {
                                        "type": "string",
                                        "description": "Nome do gateway se aplicável (mercadopago, asaas, pagarme, infinitipay...)"
                                    },
                                    "gateway_payment_id": {
                                        "type": "string",
                                        "description": "ID externo do pagamento no gateway"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": "Observação livre"
                                    }
                                },
                                "required": [
                                    "valor",
                                    "forma_pagamento"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/reservas/{id}/cancel": {
            "post": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Cancelar reserva",
                "description": "Cancela a reserva e todos os passageiros associados. Dispara webhook reserva.cancelada.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Reserva cancelada.",
                                    "data": {
                                        "id": 501,
                                        "status": "cancelado"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/reservas/{id}/magic-link": {
            "post": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Gerar magic link da reserva",
                "description": "Gera URL única (válida 30 minutos, single-use) que loga o comprador e redireciona para a página da reserva no portal cliente. Útil para enviar via WhatsApp/email pós-pagamento e pedir que o cliente complete documentos/contrato.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Magic link da reserva gerado.",
                                    "data": {
                                        "reserva_id": 501,
                                        "codigo": "VG-ABC12345",
                                        "cliente_id": 123,
                                        "magic_link_url": "https://tenant.viagilize.com.br/auth/magic/abc123def456?redirect=%2Fminha-conta%2Freservas%2FVG-ABC12345",
                                        "expires_at": "2026-04-25T22:00:00-03:00",
                                        "single_use": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/reservas/{id}/contrato-status": {
            "get": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Status do contrato da reserva",
                "description": "Retorna o status do aceite eletrônico do contrato por passageiro da reserva. Inclui referência ao SignatureAgreement ativo (se houver). O fluxo recomendado é: pagar primeiro (via payment-link) → gerar magic-link → cliente assina pelo portal.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "reserva_id": 501,
                                        "codigo": "VG-ABC12345",
                                        "exige_contrato": true,
                                        "passageiros": [
                                            {
                                                "passageiro_id": 1001,
                                                "codigo_reserva": "VGABC12345",
                                                "cliente_id": 123,
                                                "nome": "Maria Silva Santos",
                                                "aceite_status": false,
                                                "aceite_data": null,
                                                "aceite_ip": null,
                                                "agreement": {
                                                    "id": 891,
                                                    "status": "pending",
                                                    "created_at": "2026-04-25T19:15:00-03:00",
                                                    "signed_at": null
                                                }
                                            }
                                        ],
                                        "fluxo": "O aceite acontece pelo portal do cliente apos o pagamento, via magic link em /minha-conta/excursao/{id}/contrato. Use POST /reservas/{id}/magic-link para gerar."
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/reservas/{id}/passageiros-pendentes": {
            "get": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Listar vagas pendentes",
                "description": "Lista as vagas pendentes (passageiros placeholder aguardando preenchimento). Cada vaga retorna o link_convite — URL pública do formulário que pode ser copiada e enviada via WhatsApp/email para o convidado preencher, ou usada pelo comprador no portal. **Auto-renovação:** se o token de uma vaga ainda pendente estiver expirado/usado, este endpoint regenera automaticamente um token novo (24h de validade) antes de retornar. Não é necessário chamar o endpoint dedicado de reenviar-convite — basta consultar este GET periodicamente.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "reserva_id": 501,
                                        "codigo": "VG-ABC12345",
                                        "total_pendentes": 2,
                                        "vagas_pendentes": [
                                            {
                                                "pendente_id": 10,
                                                "posicao": 2,
                                                "valor": 1450,
                                                "status": "pendente",
                                                "preco_id": 77,
                                                "transporte_id": 9,
                                                "transporte_nome": "Ônibus 01",
                                                "embarque_id": 12,
                                                "embarque_nome": "Terminal Tietê",
                                                "expira_em": "2026-05-26T18:30:42-03:00",
                                                "link_convite": "https://tenant.viagilize.com.br/convite/abc123def456...",
                                                "created_at": "2026-05-19T10:00:00-03:00"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/reservas/{id}/passageiros-pendentes/{pendenteId}/preencher": {
            "post": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Preencher vaga pendente",
                "description": "Preenche os dados de uma vaga pendente em nome do comprador. Atualiza o ExcursaoPassageiro placeholder com os dados reais. Aceita 1 de 3 formas: (a) cliente_id de cliente existente, (b) dependente_id do comprador, ou (c) dados crus (nome+cpf+...) que cria/reusa cliente por CPF (LGPD).",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "pendenteId",
                        "in": "path",
                        "required": true,
                        "description": "ID da vaga pendente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Vaga preenchida com sucesso.",
                                    "data": {
                                        "passageiro": {
                                            "id": 1002,
                                            "nome": "João Silva",
                                            "cpf": "12345678901",
                                            "cliente_id": 245,
                                            "cadastrado_via": "preenchido_comprador"
                                        },
                                        "pendente_id": 10
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "Forma A: usa cliente já cadastrado"
                                    },
                                    "dependente_id": {
                                        "type": "integer",
                                        "description": "Forma B: usa dependente do comprador"
                                    },
                                    "nome": {
                                        "type": "string",
                                        "description": "Forma C (com cpf): cria/reusa cliente"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "Forma C (com nome): aceita com/sem formatação"
                                    },
                                    "rg": {
                                        "type": "string",
                                        "description": "RG do passageiro (opcional)"
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone/celular do passageiro (opcional)"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail do passageiro (opcional)"
                                    },
                                    "data_nascimento": {
                                        "type": "string",
                                        "description": "Data de nascimento (YYYY-MM-DD, opcional)"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/reservas/{id}/passageiros-pendentes/{pendenteId}/reenviar-convite": {
            "post": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Regenerar link de convite",
                "description": "Invalida o token atual e gera um novo (validade padrão 24h). Use para recuperar vaga com link_convite expirado. Não dispara envio por canal — quem decide se reencaminha por WhatsApp/email é o integrador.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "pendenteId",
                        "in": "path",
                        "required": true,
                        "description": "ID da vaga pendente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Convite regenerado.",
                                    "data": {
                                        "pendente_id": 10,
                                        "link_convite": "https://tenant.viagilize.com.br/convite/abc123token",
                                        "expira_em": "2026-05-20T13:00:00-03:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/reservas/{id}/passageiros-pendentes/{pendenteId}": {
            "delete": {
                "tags": [
                    "Reservas"
                ],
                "summary": "Cancelar vaga pendente",
                "description": "Cancela uma vaga pendente não preenchida. O valor da vaga é subtraído de valor_total/valor_pendente do pedido. Token de convite associado é invalidado.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "pendenteId",
                        "in": "path",
                        "required": true,
                        "description": "ID da vaga pendente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Vaga pendente cancelada."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/lista-espera": {
            "get": {
                "tags": [
                    "Lista de Espera"
                ],
                "summary": "Listar entradas",
                "description": "Lista paginada das entradas em lista de espera, com filtros.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Página",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens (max 100)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "excursao_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "aguardando, notificado, expirado, cancelado, convertido",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cliente_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por cliente",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 17,
                                            "excursao_id": 45,
                                            "cliente_id": 123,
                                            "nome": "Maria Silva Santos",
                                            "email": "maria@example.com",
                                            "celular": "85988887777",
                                            "cpf": "12345678901",
                                            "quantidade": 2,
                                            "observacoes": "Aceita troca de embarque se houver",
                                            "posicao": 3,
                                            "status": "aguardando",
                                            "origem": "api",
                                            "created_at": "2026-04-25T15:00:00-03:00"
                                        }
                                    ],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 7
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Lista de Espera"
                ],
                "summary": "Adicionar à lista de espera",
                "description": "Adiciona uma pessoa na fila. Posição é calculada automaticamente (ultima da fila para essa excursão).",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Entrada criada na lista de espera.",
                                    "data": {
                                        "id": 17,
                                        "excursao_id": 45,
                                        "cliente_id": 123,
                                        "nome": "Maria Silva Santos",
                                        "email": "maria@example.com",
                                        "celular": "85988887777",
                                        "cpf": "12345678901",
                                        "quantidade": 2,
                                        "observacoes": "Aceita troca de embarque se houver",
                                        "posicao": 3,
                                        "status": "aguardando",
                                        "origem": "api",
                                        "created_at": "2026-04-25T15:00:00-03:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "excursao_id": {
                                        "type": "integer",
                                        "description": "ID da excursão"
                                    },
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "ID de cliente existente (alternativa a passar nome/email/celular)"
                                    },
                                    "nome": {
                                        "type": "string",
                                        "description": "Obrigatorio se cliente_id nao for informado"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "Email para notificacao quando vaga abrir"
                                    },
                                    "celular": {
                                        "type": "string",
                                        "description": "Celular para notificacao via WhatsApp"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "CPF (opcional)"
                                    },
                                    "quantidade": {
                                        "type": "integer",
                                        "description": "Quantas vagas reservar (1-20, default 1)"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observacoes livres"
                                    }
                                },
                                "required": [
                                    "excursao_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/lista-espera/{id}": {
            "get": {
                "tags": [
                    "Lista de Espera"
                ],
                "summary": "Detalhes da entrada",
                "description": "Retorna a entrada com cliente e excursão carregados.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da entrada",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 17,
                                        "excursao_id": 45,
                                        "cliente_id": 123,
                                        "nome": "Maria Silva Santos",
                                        "email": "maria@example.com",
                                        "celular": "85988887777",
                                        "cpf": "12345678901",
                                        "quantidade": 2,
                                        "observacoes": "Aceita troca de embarque se houver",
                                        "posicao": 3,
                                        "status": "aguardando",
                                        "origem": "api",
                                        "created_at": "2026-04-25T15:00:00-03:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Lista de Espera"
                ],
                "summary": "Remover da fila",
                "description": "Marca a entrada como cancelada. Posicoes seguintes nao sao reordenadas automaticamente.",
                "security": [
                    {
                        "bearerAuth": [
                            "reservas:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da entrada",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Entrada removida da lista de espera."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/passageiros/{passageiroId}/financeiro": {
            "get": {
                "tags": [
                    "Financeiro"
                ],
                "summary": "Dados financeiros do passageiro",
                "description": "Resumo financeiro: valor total, pago, pendente, status.",
                "security": [
                    {
                        "bearerAuth": [
                            "financeiro:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "passageiroId",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 301,
                                        "passageiro_id": 1001,
                                        "valor_original": 1450,
                                        "valor_desconto": 0,
                                        "valor_total": 1450,
                                        "valor_pago": 725,
                                        "valor_pendente": 725,
                                        "percentual_pago": 50,
                                        "forma_pagamento": "pix",
                                        "parcelas": 2,
                                        "status": "parcial",
                                        "ultimo_pagamento_em": "2024-10-20T14:22:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/passageiros/{passageiroId}/pagamentos": {
            "get": {
                "tags": [
                    "Financeiro"
                ],
                "summary": "Listar pagamentos",
                "description": "Lista todos os pagamentos registrados para um passageiro.",
                "security": [
                    {
                        "bearerAuth": [
                            "financeiro:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "passageiroId",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 501,
                                            "passageiro_id": 1001,
                                            "valor": 725,
                                            "forma": "pix",
                                            "gateway": "mercado_pago",
                                            "gateway_payment_id": "mp_12345",
                                            "data_pagamento": "2024-10-20",
                                            "observacao": null,
                                            "created_at": "2024-10-20T14:22:00Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Financeiro"
                ],
                "summary": "Registrar pagamento",
                "description": "Registra um pagamento manual (ex: recebido em dinheiro, transferência). Atualiza valor_pago do passageiro/order.",
                "security": [
                    {
                        "bearerAuth": [
                            "financeiro:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "passageiroId",
                        "in": "path",
                        "required": true,
                        "description": "ID do passageiro",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Pagamento registrado.",
                                    "data": {
                                        "id": 502,
                                        "valor": 725,
                                        "forma": "pix",
                                        "data_pagamento": "2024-10-25"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "valor": {
                                        "type": "number",
                                        "description": "Valor pago (>= 0.01)"
                                    },
                                    "forma": {
                                        "type": "string",
                                        "description": "pix, cartao, boleto, dinheiro, transferencia, cheque"
                                    },
                                    "data_pagamento": {
                                        "type": "string",
                                        "description": "Data do pagamento (default: hoje)"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": "Observações"
                                    }
                                },
                                "required": [
                                    "valor",
                                    "forma"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/financeiro/resumo": {
            "get": {
                "tags": [
                    "Financeiro"
                ],
                "summary": "Resumo financeiro da excursão",
                "description": "Agrega valores de todos os passageiros da excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "financeiro:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "totais": {
                                            "passageiros": 45,
                                            "com_financeiro": 45,
                                            "valor_total": 65250,
                                            "valor_pago": 32625,
                                            "valor_pendente": 32625,
                                            "percentual_pago": 50
                                        },
                                        "por_status": {
                                            "pendente": 10,
                                            "parcial": 25,
                                            "pago": 10,
                                            "cancelado": 0,
                                            "reembolsado": 0
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/cupons": {
            "get": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Listar cupons",
                "description": "Lista paginada de cupons com filtros opcionais.",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por código ou nome",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "Filtra por status ativo",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "tipo",
                        "in": "query",
                        "required": false,
                        "description": "publico | unico | cliente | primeira_compra | indicacao",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "apenas_principais",
                        "in": "query",
                        "required": false,
                        "description": "Se true, omite cupons filhos de lotes",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens por página (default 50, máx 100)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 42,
                                            "codigo": "VERAO50",
                                            "nome": "Promoção Verão 2026",
                                            "descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
                                            "tipo": "publico",
                                            "tipo_label": "Público",
                                            "tipo_desconto": "percentual",
                                            "tipo_desconto_label": "Percentual",
                                            "valor_desconto": 15,
                                            "desconto_formatado": "15%",
                                            "valor_maximo_desconto": 300,
                                            "valor_minimo_pedido": 500,
                                            "limite_uso_total": 100,
                                            "limite_uso_por_cliente": 1,
                                            "usos": 27,
                                            "usos_disponiveis": 73,
                                            "usos_progresso": "27/100",
                                            "data_inicio": "2026-01-01T00:00:00Z",
                                            "data_expiracao": "2026-02-28T23:59:59Z",
                                            "excursoes_permitidas": null,
                                            "excursoes_excluidas": null,
                                            "categorias_permitidas": null,
                                            "apenas_primeira_compra": false,
                                            "clientes_permitidos": null,
                                            "clientes_bloqueados": null,
                                            "cupom_pai_id": null,
                                            "lote_nome": null,
                                            "is_lote": false,
                                            "is_filho_lote": false,
                                            "ativo": true,
                                            "status": "Ativo",
                                            "status_color": "green",
                                            "valido": true,
                                            "created_at": "2025-12-15T10:00:00Z",
                                            "updated_at": "2026-01-10T14:30:00Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Criar cupom",
                "description": "Cria um novo cupom de desconto. O código é normalizado para uppercase. Retorna 409 se já existir.",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cupom criado com sucesso.",
                                    "data": {
                                        "id": 42,
                                        "codigo": "VERAO50",
                                        "nome": "Promoção Verão 2026",
                                        "descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
                                        "tipo": "publico",
                                        "tipo_label": "Público",
                                        "tipo_desconto": "percentual",
                                        "tipo_desconto_label": "Percentual",
                                        "valor_desconto": 15,
                                        "desconto_formatado": "15%",
                                        "valor_maximo_desconto": 300,
                                        "valor_minimo_pedido": 500,
                                        "limite_uso_total": 100,
                                        "limite_uso_por_cliente": 1,
                                        "usos": 27,
                                        "usos_disponiveis": 73,
                                        "usos_progresso": "27/100",
                                        "data_inicio": "2026-01-01T00:00:00Z",
                                        "data_expiracao": "2026-02-28T23:59:59Z",
                                        "excursoes_permitidas": null,
                                        "excursoes_excluidas": null,
                                        "categorias_permitidas": null,
                                        "apenas_primeira_compra": false,
                                        "clientes_permitidos": null,
                                        "clientes_bloqueados": null,
                                        "cupom_pai_id": null,
                                        "lote_nome": null,
                                        "is_lote": false,
                                        "is_filho_lote": false,
                                        "ativo": true,
                                        "status": "Ativo",
                                        "status_color": "green",
                                        "valido": true,
                                        "created_at": "2025-12-15T10:00:00Z",
                                        "updated_at": "2026-01-10T14:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "codigo": {
                                        "type": "string",
                                        "description": "Código que o cliente digita no checkout (case-insensitive, hífens/espaços ignorados). Ex: VERAO50"
                                    },
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome interno do cupom (visível no admin)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição opcional"
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "publico | unico | cliente | primeira_compra | indicacao"
                                    },
                                    "tipo_desconto": {
                                        "type": "string",
                                        "description": "percentual | valor_fixo | valor_por_passageiro | frete_gratis"
                                    },
                                    "valor_desconto": {
                                        "type": "number",
                                        "description": "Valor do desconto. Em percentual: 0-100. Em valor_fixo: R$. Em valor_por_passageiro: R$ por pax"
                                    },
                                    "valor_maximo_desconto": {
                                        "type": "number",
                                        "description": "Teto do desconto em R$ (útil para percentuais)"
                                    },
                                    "limite_uso_total": {
                                        "type": "integer",
                                        "description": "Quantas vezes o cupom pode ser usado no total (null = ilimitado)"
                                    },
                                    "limite_uso_por_cliente": {
                                        "type": "integer",
                                        "description": "Quantas vezes cada cliente pode usar (null = ilimitado)"
                                    },
                                    "valor_minimo_pedido": {
                                        "type": "number",
                                        "description": "Valor mínimo do pedido para o cupom valer"
                                    },
                                    "data_inicio": {
                                        "type": "string",
                                        "description": "Início da vigência (ISO 8601). null = vale desde já"
                                    },
                                    "data_expiracao": {
                                        "type": "string",
                                        "description": "Fim da vigência (ISO 8601). null = sem expiração"
                                    },
                                    "excursoes_permitidas": {
                                        "type": "array",
                                        "description": "IDs de excursões em que o cupom é válido (null = todas)"
                                    },
                                    "excursoes_excluidas": {
                                        "type": "array",
                                        "description": "IDs de excursões em que o cupom NÃO vale"
                                    },
                                    "categorias_permitidas": {
                                        "type": "array",
                                        "description": "IDs de categorias de passageiro permitidas"
                                    },
                                    "apenas_primeira_compra": {
                                        "type": "boolean",
                                        "description": "Se true, só vale para clientes sem compra anterior"
                                    },
                                    "clientes_permitidos": {
                                        "type": "array",
                                        "description": "IDs de clientes que podem usar (null = todos)"
                                    },
                                    "clientes_bloqueados": {
                                        "type": "array",
                                        "description": "IDs de clientes que NÃO podem usar"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Cupom ativo (default true)"
                                    }
                                },
                                "required": [
                                    "codigo",
                                    "nome",
                                    "tipo",
                                    "tipo_desconto"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/cupons/{id}": {
            "get": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Detalhes do cupom",
                "description": "Retorna todos os campos do cupom + contagem de usos e status calculado.",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cupom",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 42,
                                        "codigo": "VERAO50",
                                        "nome": "Promoção Verão 2026",
                                        "descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
                                        "tipo": "publico",
                                        "tipo_label": "Público",
                                        "tipo_desconto": "percentual",
                                        "tipo_desconto_label": "Percentual",
                                        "valor_desconto": 15,
                                        "desconto_formatado": "15%",
                                        "valor_maximo_desconto": 300,
                                        "valor_minimo_pedido": 500,
                                        "limite_uso_total": 100,
                                        "limite_uso_por_cliente": 1,
                                        "usos": 27,
                                        "usos_disponiveis": 73,
                                        "usos_progresso": "27/100",
                                        "data_inicio": "2026-01-01T00:00:00Z",
                                        "data_expiracao": "2026-02-28T23:59:59Z",
                                        "excursoes_permitidas": null,
                                        "excursoes_excluidas": null,
                                        "categorias_permitidas": null,
                                        "apenas_primeira_compra": false,
                                        "clientes_permitidos": null,
                                        "clientes_bloqueados": null,
                                        "cupom_pai_id": null,
                                        "lote_nome": null,
                                        "is_lote": false,
                                        "is_filho_lote": false,
                                        "ativo": true,
                                        "status": "Ativo",
                                        "status_color": "green",
                                        "valido": true,
                                        "created_at": "2025-12-15T10:00:00Z",
                                        "updated_at": "2026-01-10T14:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Atualizar cupom",
                "description": "Atualiza os campos do cupom. Todos os campos são opcionais (envie apenas os que mudaram).",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cupom",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cupom atualizado com sucesso.",
                                    "data": {
                                        "id": 42,
                                        "codigo": "VERAO50",
                                        "nome": "Promoção Verão 2026",
                                        "descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
                                        "tipo": "publico",
                                        "tipo_label": "Público",
                                        "tipo_desconto": "percentual",
                                        "tipo_desconto_label": "Percentual",
                                        "valor_desconto": 15,
                                        "desconto_formatado": "15%",
                                        "valor_maximo_desconto": 300,
                                        "valor_minimo_pedido": 500,
                                        "limite_uso_total": 100,
                                        "limite_uso_por_cliente": 1,
                                        "usos": 27,
                                        "usos_disponiveis": 73,
                                        "usos_progresso": "27/100",
                                        "data_inicio": "2026-01-01T00:00:00Z",
                                        "data_expiracao": "2026-02-28T23:59:59Z",
                                        "excursoes_permitidas": null,
                                        "excursoes_excluidas": null,
                                        "categorias_permitidas": null,
                                        "apenas_primeira_compra": false,
                                        "clientes_permitidos": null,
                                        "clientes_bloqueados": null,
                                        "cupom_pai_id": null,
                                        "lote_nome": null,
                                        "is_lote": false,
                                        "is_filho_lote": false,
                                        "ativo": true,
                                        "status": "Ativo",
                                        "status_color": "green",
                                        "valido": true,
                                        "created_at": "2025-12-15T10:00:00Z",
                                        "updated_at": "2026-01-10T14:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "codigo": {
                                        "type": "string",
                                        "description": "Código que o cliente digita no checkout (case-insensitive, hífens/espaços ignorados). Ex: VERAO50"
                                    },
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome interno do cupom (visível no admin)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição opcional"
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "publico | unico | cliente | primeira_compra | indicacao"
                                    },
                                    "tipo_desconto": {
                                        "type": "string",
                                        "description": "percentual | valor_fixo | valor_por_passageiro | frete_gratis"
                                    },
                                    "valor_desconto": {
                                        "type": "number",
                                        "description": "Valor do desconto. Em percentual: 0-100. Em valor_fixo: R$. Em valor_por_passageiro: R$ por pax"
                                    },
                                    "valor_maximo_desconto": {
                                        "type": "number",
                                        "description": "Teto do desconto em R$ (útil para percentuais)"
                                    },
                                    "limite_uso_total": {
                                        "type": "integer",
                                        "description": "Quantas vezes o cupom pode ser usado no total (null = ilimitado)"
                                    },
                                    "limite_uso_por_cliente": {
                                        "type": "integer",
                                        "description": "Quantas vezes cada cliente pode usar (null = ilimitado)"
                                    },
                                    "valor_minimo_pedido": {
                                        "type": "number",
                                        "description": "Valor mínimo do pedido para o cupom valer"
                                    },
                                    "data_inicio": {
                                        "type": "string",
                                        "description": "Início da vigência (ISO 8601). null = vale desde já"
                                    },
                                    "data_expiracao": {
                                        "type": "string",
                                        "description": "Fim da vigência (ISO 8601). null = sem expiração"
                                    },
                                    "excursoes_permitidas": {
                                        "type": "array",
                                        "description": "IDs de excursões em que o cupom é válido (null = todas)"
                                    },
                                    "excursoes_excluidas": {
                                        "type": "array",
                                        "description": "IDs de excursões em que o cupom NÃO vale"
                                    },
                                    "categorias_permitidas": {
                                        "type": "array",
                                        "description": "IDs de categorias de passageiro permitidas"
                                    },
                                    "apenas_primeira_compra": {
                                        "type": "boolean",
                                        "description": "Se true, só vale para clientes sem compra anterior"
                                    },
                                    "clientes_permitidos": {
                                        "type": "array",
                                        "description": "IDs de clientes que podem usar (null = todos)"
                                    },
                                    "clientes_bloqueados": {
                                        "type": "array",
                                        "description": "IDs de clientes que NÃO podem usar"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Cupom ativo (default true)"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Excluir cupom",
                "description": "Remove permanentemente o cupom. Retorna 400 se já foi utilizado em alguma reserva (desative-o em vez de excluir).",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cupom",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cupom excluído com sucesso."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/cupons/{id}/status": {
            "patch": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Alternar ativo/inativo",
                "description": "Inverte o status ativo do cupom (toggle). Útil para pausar/retomar um cupom sem excluí-lo.",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do cupom",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Status do cupom atualizado.",
                                    "data": {
                                        "id": 42,
                                        "codigo": "VERAO50",
                                        "nome": "Promoção Verão 2026",
                                        "descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
                                        "tipo": "publico",
                                        "tipo_label": "Público",
                                        "tipo_desconto": "percentual",
                                        "tipo_desconto_label": "Percentual",
                                        "valor_desconto": 15,
                                        "desconto_formatado": "15%",
                                        "valor_maximo_desconto": 300,
                                        "valor_minimo_pedido": 500,
                                        "limite_uso_total": 100,
                                        "limite_uso_por_cliente": 1,
                                        "usos": 27,
                                        "usos_disponiveis": 73,
                                        "usos_progresso": "27/100",
                                        "data_inicio": "2026-01-01T00:00:00Z",
                                        "data_expiracao": "2026-02-28T23:59:59Z",
                                        "excursoes_permitidas": null,
                                        "excursoes_excluidas": null,
                                        "categorias_permitidas": null,
                                        "apenas_primeira_compra": false,
                                        "clientes_permitidos": null,
                                        "clientes_bloqueados": null,
                                        "cupom_pai_id": null,
                                        "lote_nome": null,
                                        "is_lote": false,
                                        "is_filho_lote": false,
                                        "ativo": false,
                                        "status": "Ativo",
                                        "status_color": "green",
                                        "valido": true,
                                        "created_at": "2025-12-15T10:00:00Z",
                                        "updated_at": "2026-01-10T14:30:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/cupons/validar": {
            "post": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Validar cupom (sem aplicar)",
                "description": "Verifica se o código é válido e calcula o desconto. Útil para mostrar o desconto no checkout antes de confirmar. Não consome o cupom.",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:validate"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cupom válido.",
                                    "data": {
                                        "success": true,
                                        "cupom": {
                                            "id": 42,
                                            "codigo": "VERAO50",
                                            "nome": "Promoção Verão 2026",
                                            "tipo_desconto": "percentual",
                                            "desconto_formatado": "15%"
                                        },
                                        "desconto": 180,
                                        "desconto_formatado": "R$ 180,00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "codigo": {
                                        "type": "string",
                                        "description": "Código do cupom (case-insensitive)"
                                    },
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "ID do cliente (necessário para tipos cliente/primeira_compra/indicacao)"
                                    },
                                    "valor_total": {
                                        "type": "number",
                                        "description": "Valor total do pedido em R$ (para validar valor_minimo_pedido)"
                                    },
                                    "excursao_id": {
                                        "type": "integer",
                                        "description": "ID da excursão (para validar excursoes_permitidas/excluidas)"
                                    },
                                    "quantidade_passageiros": {
                                        "type": "integer",
                                        "description": "Quantidade de passageiros (necessário para tipo_desconto=valor_por_passageiro). Default: 1"
                                    }
                                },
                                "required": [
                                    "codigo"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/cupons/aplicar/{orderId}": {
            "post": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Aplicar cupom em reserva",
                "description": "Aplica o cupom em uma reserva existente. Operação atômica com lock no cupom (evita race condition em limite_uso_total). Atualiza valor_total da order, registra CupomUso e incrementa o contador de usos.",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:validate"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "orderId",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva (Order)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cupom aplicado com sucesso.",
                                    "data": {
                                        "success": true,
                                        "desconto": 180,
                                        "desconto_formatado": "R$ 180,00",
                                        "valor_original": 1200,
                                        "valor_total": 1020
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "codigo": {
                                        "type": "string",
                                        "description": "Código do cupom"
                                    },
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "ID do cliente comprador"
                                    }
                                },
                                "required": [
                                    "codigo",
                                    "cliente_id"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Cupons"
                ],
                "summary": "Remover cupom da reserva",
                "description": "Remove o cupom aplicado em uma reserva, restaurando o valor_total original. Decrementa o contador de usos.",
                "security": [
                    {
                        "bearerAuth": [
                            "cupons:validate"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "orderId",
                        "in": "path",
                        "required": true,
                        "description": "ID da reserva",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Cupom removido com sucesso.",
                                    "data": {
                                        "success": true,
                                        "valor_total": 1200
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/guias": {
            "get": {
                "tags": [
                    "Guias"
                ],
                "summary": "Listar guias",
                "description": "Lista paginada de guias com filtros.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Buscar por nome",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por ativo",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens por página",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 7,
                                            "nome": "Carlos Santos",
                                            "email": "carlos@guides.com",
                                            "cpf": "98765432100",
                                            "telefone": "1144445555",
                                            "celular": "11988887777",
                                            "data_nascimento": "1985-03-20",
                                            "banco": "Itaú",
                                            "agencia": "0001",
                                            "conta": "12345678",
                                            "tipo_conta": "corrente",
                                            "pix": "carlos@guides.com",
                                            "ativo": true,
                                            "created_at": "2024-01-10T09:00:00Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Guias"
                ],
                "summary": "Criar guia",
                "description": "Cadastra um novo guia.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Guia cadastrado com sucesso.",
                                    "data": {
                                        "id": 7,
                                        "nome": "Carlos Santos",
                                        "email": "carlos@guides.com",
                                        "cpf": "98765432100",
                                        "telefone": "1144445555",
                                        "celular": "11988887777",
                                        "data_nascimento": "1985-03-20",
                                        "banco": "Itaú",
                                        "agencia": "0001",
                                        "conta": "12345678",
                                        "tipo_conta": "corrente",
                                        "pix": "carlos@guides.com",
                                        "ativo": true,
                                        "created_at": "2024-01-10T09:00:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome completo"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail"
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone fixo"
                                    },
                                    "celular": {
                                        "type": "string",
                                        "description": "Celular"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "CPF"
                                    },
                                    "rg": {
                                        "type": "string",
                                        "description": "RG"
                                    },
                                    "data_nascimento": {
                                        "type": "string",
                                        "description": "Nascimento (Y-m-d)"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço"
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Número"
                                    },
                                    "complemento": {
                                        "type": "string",
                                        "description": "Complemento"
                                    },
                                    "bairro": {
                                        "type": "string",
                                        "description": "Bairro"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF"
                                    },
                                    "banco": {
                                        "type": "string",
                                        "description": "Banco (para repasses)"
                                    },
                                    "agencia": {
                                        "type": "string",
                                        "description": "Agência"
                                    },
                                    "conta": {
                                        "type": "string",
                                        "description": "Conta"
                                    },
                                    "tipo_conta": {
                                        "type": "string",
                                        "description": "corrente, poupanca"
                                    },
                                    "pix": {
                                        "type": "string",
                                        "description": "Chave PIX"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Guia ativo (default true)"
                                    }
                                },
                                "required": [
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/guias/{id}": {
            "get": {
                "tags": [
                    "Guias"
                ],
                "summary": "Detalhes do guia",
                "description": "Retorna todos os dados do guia.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 7,
                                        "nome": "Carlos Santos",
                                        "email": "carlos@guides.com",
                                        "cpf": "98765432100",
                                        "telefone": "1144445555",
                                        "celular": "11988887777",
                                        "data_nascimento": "1985-03-20",
                                        "banco": "Itaú",
                                        "agencia": "0001",
                                        "conta": "12345678",
                                        "tipo_conta": "corrente",
                                        "pix": "carlos@guides.com",
                                        "ativo": true,
                                        "created_at": "2024-01-10T09:00:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Guias"
                ],
                "summary": "Atualizar guia",
                "description": "Atualiza os dados do guia.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Guia atualizado.",
                                    "data": {
                                        "id": 7,
                                        "nome": "Carlos Santos",
                                        "email": "carlos@guides.com",
                                        "cpf": "98765432100",
                                        "telefone": "1144445555",
                                        "celular": "11988887777",
                                        "data_nascimento": "1985-03-20",
                                        "banco": "Itaú",
                                        "agencia": "0001",
                                        "conta": "12345678",
                                        "tipo_conta": "corrente",
                                        "pix": "carlos@guides.com",
                                        "ativo": true,
                                        "created_at": "2024-01-10T09:00:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome completo"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail"
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone fixo"
                                    },
                                    "celular": {
                                        "type": "string",
                                        "description": "Celular"
                                    },
                                    "cpf": {
                                        "type": "string",
                                        "description": "CPF"
                                    },
                                    "rg": {
                                        "type": "string",
                                        "description": "RG"
                                    },
                                    "data_nascimento": {
                                        "type": "string",
                                        "description": "Nascimento (Y-m-d)"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço"
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Número"
                                    },
                                    "complemento": {
                                        "type": "string",
                                        "description": "Complemento"
                                    },
                                    "bairro": {
                                        "type": "string",
                                        "description": "Bairro"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF"
                                    },
                                    "banco": {
                                        "type": "string",
                                        "description": "Banco (para repasses)"
                                    },
                                    "agencia": {
                                        "type": "string",
                                        "description": "Agência"
                                    },
                                    "conta": {
                                        "type": "string",
                                        "description": "Conta"
                                    },
                                    "tipo_conta": {
                                        "type": "string",
                                        "description": "corrente, poupanca"
                                    },
                                    "pix": {
                                        "type": "string",
                                        "description": "Chave PIX"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Guia ativo (default true)"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Guias"
                ],
                "summary": "Excluir guia",
                "description": "Remove o guia.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Guia excluído."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/guias/{id}/status": {
            "patch": {
                "tags": [
                    "Guias"
                ],
                "summary": "Alterar status ativo/inativo",
                "description": "Ativa ou desativa o guia.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Status alterado.",
                                    "data": {
                                        "ativo": false
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/guias": {
            "get": {
                "tags": [
                    "Guias"
                ],
                "summary": "Listar guias da excursão",
                "description": "Lista os guias designados para uma excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 51,
                                            "excursao_id": 45,
                                            "guia_id": 7,
                                            "funcao": "guia_principal",
                                            "valor_pagamento": 800,
                                            "guia": {
                                                "id": 7,
                                                "nome": "Carlos Santos",
                                                "email": "carlos@guides.com",
                                                "cpf": "98765432100",
                                                "telefone": "1144445555",
                                                "celular": "11988887777",
                                                "data_nascimento": "1985-03-20",
                                                "banco": "Itaú",
                                                "agencia": "0001",
                                                "conta": "12345678",
                                                "tipo_conta": "corrente",
                                                "pix": "carlos@guides.com",
                                                "ativo": true,
                                                "created_at": "2024-01-10T09:00:00Z"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Guias"
                ],
                "summary": "Designar guia",
                "description": "Designa um guia para a excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "guias:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Guia designado.",
                                    "data": {
                                        "id": 51,
                                        "excursao_id": 45,
                                        "guia_id": 7,
                                        "funcao": "guia_principal"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "guia_id": {
                                        "type": "integer",
                                        "description": "ID do guia"
                                    },
                                    "transporte_id": {
                                        "type": "integer",
                                        "description": "ID do transporte específico (se múltiplos)"
                                    },
                                    "embarque_id": {
                                        "type": "integer",
                                        "description": "ID do embarque"
                                    },
                                    "funcao": {
                                        "type": "string",
                                        "description": "guia_principal, guia_auxiliar, monitor"
                                    },
                                    "valor_pagamento": {
                                        "type": "number",
                                        "description": "Valor a pagar ao guia"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": "Observação"
                                    }
                                },
                                "required": [
                                    "guia_id",
                                    "funcao"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/veiculos": {
            "get": {
                "tags": [
                    "Veículos"
                ],
                "summary": "Listar veículos",
                "description": "Lista veículos com filtros.",
                "security": [
                    {
                        "bearerAuth": [
                            "veiculos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "tipo",
                        "in": "query",
                        "required": false,
                        "description": "Tipo do veículo",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "transporte_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar pela empresa dona",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por ativo",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por modelo, placa",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 5,
                                            "transporte_id": 2,
                                            "tipo": "onibus_leito",
                                            "modelo": "Paradiso 1600 LD",
                                            "placa": "ABC-1234",
                                            "renavam": "12345678901",
                                            "ano_fabricacao": 2019,
                                            "capacidade_total": 46,
                                            "ar_condicionado": true,
                                            "wifi": true,
                                            "banheiro": true,
                                            "tv": true,
                                            "tomadas": true,
                                            "reclinavel": false,
                                            "ativo": true,
                                            "transporte": {
                                                "id": 2,
                                                "nome_fantasia": "Viagens Brasil Express",
                                                "cnpj": "12.345.678/0001-90"
                                            },
                                            "created_at": "2024-01-05T15:45:00Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Veículos"
                ],
                "summary": "Criar veículo",
                "description": "Cadastra um veículo vinculado a uma empresa de transporte.",
                "security": [
                    {
                        "bearerAuth": [
                            "veiculos:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Veículo criado.",
                                    "data": {
                                        "id": 5,
                                        "transporte_id": 2,
                                        "tipo": "onibus_leito",
                                        "modelo": "Paradiso 1600 LD",
                                        "placa": "ABC-1234",
                                        "renavam": "12345678901",
                                        "ano_fabricacao": 2019,
                                        "capacidade_total": 46,
                                        "ar_condicionado": true,
                                        "wifi": true,
                                        "banheiro": true,
                                        "tv": true,
                                        "tomadas": true,
                                        "reclinavel": false,
                                        "ativo": true,
                                        "transporte": {
                                            "id": 2,
                                            "nome_fantasia": "Viagens Brasil Express",
                                            "cnpj": "12.345.678/0001-90"
                                        },
                                        "created_at": "2024-01-05T15:45:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "transporte_id": {
                                        "type": "integer",
                                        "description": "ID da empresa de transporte dona do veículo"
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "van, micro_onibus, onibus, onibus_leito, onibus_semileito, onibus_executivo, onibus_double_decker, minivan, carro"
                                    },
                                    "modelo": {
                                        "type": "string",
                                        "description": "Modelo (ex: Mercedes-Benz O-500)"
                                    },
                                    "placa": {
                                        "type": "string",
                                        "description": "Placa"
                                    },
                                    "renavam": {
                                        "type": "string",
                                        "description": "RENAVAM"
                                    },
                                    "ano_fabricacao": {
                                        "type": "integer",
                                        "description": "Ano de fabricação"
                                    },
                                    "capacidade_total": {
                                        "type": "integer",
                                        "description": "Capacidade de passageiros (>=1)"
                                    },
                                    "ar_condicionado": {
                                        "type": "boolean",
                                        "description": "Tem ar-condicionado"
                                    },
                                    "wifi": {
                                        "type": "boolean",
                                        "description": "Tem Wi-Fi"
                                    },
                                    "banheiro": {
                                        "type": "boolean",
                                        "description": "Tem banheiro"
                                    },
                                    "tv": {
                                        "type": "boolean",
                                        "description": "Tem TV"
                                    },
                                    "tomadas": {
                                        "type": "boolean",
                                        "description": "Tem tomadas"
                                    },
                                    "reclinavel": {
                                        "type": "boolean",
                                        "description": "Assentos reclináveis"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Veículo ativo"
                                    }
                                },
                                "required": [
                                    "transporte_id",
                                    "tipo",
                                    "modelo",
                                    "capacidade_total"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/veiculos/tipos": {
            "get": {
                "tags": [
                    "Veículos"
                ],
                "summary": "Tipos de veículos disponíveis",
                "description": "Lista os tipos aceitos pelo campo tipo.",
                "security": [
                    {
                        "bearerAuth": [
                            "veiculos:read"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        "van",
                                        "micro_onibus",
                                        "onibus",
                                        "onibus_leito",
                                        "onibus_semileito",
                                        "onibus_executivo",
                                        "onibus_double_decker",
                                        "minivan",
                                        "carro"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/veiculos/{id}": {
            "get": {
                "tags": [
                    "Veículos"
                ],
                "summary": "Detalhes do veículo",
                "description": "Retorna o veículo com a empresa de transporte.",
                "security": [
                    {
                        "bearerAuth": [
                            "veiculos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 5,
                                        "transporte_id": 2,
                                        "tipo": "onibus_leito",
                                        "modelo": "Paradiso 1600 LD",
                                        "placa": "ABC-1234",
                                        "renavam": "12345678901",
                                        "ano_fabricacao": 2019,
                                        "capacidade_total": 46,
                                        "ar_condicionado": true,
                                        "wifi": true,
                                        "banheiro": true,
                                        "tv": true,
                                        "tomadas": true,
                                        "reclinavel": false,
                                        "ativo": true,
                                        "transporte": {
                                            "id": 2,
                                            "nome_fantasia": "Viagens Brasil Express",
                                            "cnpj": "12.345.678/0001-90"
                                        },
                                        "created_at": "2024-01-05T15:45:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Veículos"
                ],
                "summary": "Atualizar veículo",
                "description": "Atualiza parcialmente o veículo.",
                "security": [
                    {
                        "bearerAuth": [
                            "veiculos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Veículo atualizado.",
                                    "data": {
                                        "id": 5,
                                        "transporte_id": 2,
                                        "tipo": "onibus_leito",
                                        "modelo": "Paradiso 1600 LD",
                                        "placa": "ABC-1234",
                                        "renavam": "12345678901",
                                        "ano_fabricacao": 2019,
                                        "capacidade_total": 46,
                                        "ar_condicionado": true,
                                        "wifi": true,
                                        "banheiro": true,
                                        "tv": true,
                                        "tomadas": true,
                                        "reclinavel": false,
                                        "ativo": true,
                                        "transporte": {
                                            "id": 2,
                                            "nome_fantasia": "Viagens Brasil Express",
                                            "cnpj": "12.345.678/0001-90"
                                        },
                                        "created_at": "2024-01-05T15:45:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "transporte_id": {
                                        "type": "integer",
                                        "description": "ID da empresa de transporte dona do veículo"
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "van, micro_onibus, onibus, onibus_leito, onibus_semileito, onibus_executivo, onibus_double_decker, minivan, carro"
                                    },
                                    "modelo": {
                                        "type": "string",
                                        "description": "Modelo (ex: Mercedes-Benz O-500)"
                                    },
                                    "placa": {
                                        "type": "string",
                                        "description": "Placa"
                                    },
                                    "renavam": {
                                        "type": "string",
                                        "description": "RENAVAM"
                                    },
                                    "ano_fabricacao": {
                                        "type": "integer",
                                        "description": "Ano de fabricação"
                                    },
                                    "capacidade_total": {
                                        "type": "integer",
                                        "description": "Capacidade de passageiros (>=1)"
                                    },
                                    "ar_condicionado": {
                                        "type": "boolean",
                                        "description": "Tem ar-condicionado"
                                    },
                                    "wifi": {
                                        "type": "boolean",
                                        "description": "Tem Wi-Fi"
                                    },
                                    "banheiro": {
                                        "type": "boolean",
                                        "description": "Tem banheiro"
                                    },
                                    "tv": {
                                        "type": "boolean",
                                        "description": "Tem TV"
                                    },
                                    "tomadas": {
                                        "type": "boolean",
                                        "description": "Tem tomadas"
                                    },
                                    "reclinavel": {
                                        "type": "boolean",
                                        "description": "Assentos reclináveis"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Veículo ativo"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Veículos"
                ],
                "summary": "Excluir veículo",
                "description": "Remove o veículo.",
                "security": [
                    {
                        "bearerAuth": [
                            "veiculos:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Veículo excluído."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/veiculos/{id}/status": {
            "patch": {
                "tags": [
                    "Veículos"
                ],
                "summary": "Alterar status ativo/inativo",
                "description": "Alterna entre ativo e inativo.",
                "security": [
                    {
                        "bearerAuth": [
                            "veiculos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "ativo": false
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/transportes": {
            "get": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Listar empresas de transporte",
                "description": "Lista paginada com filtros.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Buscar por nome",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "Filtrar por ativo",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 2,
                                            "nome_fantasia": "Viagens Brasil Express",
                                            "razao_social": "Viagens Brasil Express LTDA",
                                            "cnpj": "12.345.678/0001-90",
                                            "email": "contato@brasilexpress.com.br",
                                            "telefone": "1133334444",
                                            "whatsapp": "11999998888",
                                            "cidade": "São Paulo",
                                            "estado": "SP",
                                            "contato_nome": "Pedro Oliveira",
                                            "contato_telefone": "11988887777",
                                            "ativo": true,
                                            "created_at": "2024-01-05T15:45:00Z"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Criar empresa",
                "description": "Cadastra uma nova empresa de transporte.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Empresa cadastrada.",
                                    "data": {
                                        "id": 2,
                                        "nome_fantasia": "Viagens Brasil Express",
                                        "razao_social": "Viagens Brasil Express LTDA",
                                        "cnpj": "12.345.678/0001-90",
                                        "email": "contato@brasilexpress.com.br",
                                        "telefone": "1133334444",
                                        "whatsapp": "11999998888",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_nome": "Pedro Oliveira",
                                        "contato_telefone": "11988887777",
                                        "ativo": true,
                                        "created_at": "2024-01-05T15:45:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome_fantasia": {
                                        "type": "string",
                                        "description": "Nome fantasia"
                                    },
                                    "razao_social": {
                                        "type": "string",
                                        "description": "Razão social"
                                    },
                                    "cnpj": {
                                        "type": "string",
                                        "description": "CNPJ"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail"
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone principal"
                                    },
                                    "telefone_secundario": {
                                        "type": "string",
                                        "description": "Telefone alternativo"
                                    },
                                    "whatsapp": {
                                        "type": "string",
                                        "description": "WhatsApp"
                                    },
                                    "site": {
                                        "type": "string",
                                        "description": "Site oficial"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço"
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Número"
                                    },
                                    "complemento": {
                                        "type": "string",
                                        "description": "Complemento"
                                    },
                                    "bairro": {
                                        "type": "string",
                                        "description": "Bairro"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF"
                                    },
                                    "contato_nome": {
                                        "type": "string",
                                        "description": "Pessoa de contato"
                                    },
                                    "contato_telefone": {
                                        "type": "string",
                                        "description": "Telefone do contato"
                                    },
                                    "contato_email": {
                                        "type": "string",
                                        "description": "E-mail do contato"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Empresa ativa"
                                    }
                                },
                                "required": [
                                    "nome_fantasia"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transportes/{id}": {
            "get": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Detalhes da empresa",
                "description": "Retorna a empresa com dados completos.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 2,
                                        "nome_fantasia": "Viagens Brasil Express",
                                        "razao_social": "Viagens Brasil Express LTDA",
                                        "cnpj": "12.345.678/0001-90",
                                        "email": "contato@brasilexpress.com.br",
                                        "telefone": "1133334444",
                                        "whatsapp": "11999998888",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_nome": "Pedro Oliveira",
                                        "contato_telefone": "11988887777",
                                        "ativo": true,
                                        "created_at": "2024-01-05T15:45:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Atualizar empresa",
                "description": "Atualiza parcialmente os dados.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Empresa atualizada.",
                                    "data": {
                                        "id": 2,
                                        "nome_fantasia": "Viagens Brasil Express",
                                        "razao_social": "Viagens Brasil Express LTDA",
                                        "cnpj": "12.345.678/0001-90",
                                        "email": "contato@brasilexpress.com.br",
                                        "telefone": "1133334444",
                                        "whatsapp": "11999998888",
                                        "cidade": "São Paulo",
                                        "estado": "SP",
                                        "contato_nome": "Pedro Oliveira",
                                        "contato_telefone": "11988887777",
                                        "ativo": true,
                                        "created_at": "2024-01-05T15:45:00Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome_fantasia": {
                                        "type": "string",
                                        "description": "Nome fantasia"
                                    },
                                    "razao_social": {
                                        "type": "string",
                                        "description": "Razão social"
                                    },
                                    "cnpj": {
                                        "type": "string",
                                        "description": "CNPJ"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "E-mail"
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": "Telefone principal"
                                    },
                                    "telefone_secundario": {
                                        "type": "string",
                                        "description": "Telefone alternativo"
                                    },
                                    "whatsapp": {
                                        "type": "string",
                                        "description": "WhatsApp"
                                    },
                                    "site": {
                                        "type": "string",
                                        "description": "Site oficial"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": "CEP"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço"
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Número"
                                    },
                                    "complemento": {
                                        "type": "string",
                                        "description": "Complemento"
                                    },
                                    "bairro": {
                                        "type": "string",
                                        "description": "Bairro"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF"
                                    },
                                    "contato_nome": {
                                        "type": "string",
                                        "description": "Pessoa de contato"
                                    },
                                    "contato_telefone": {
                                        "type": "string",
                                        "description": "Telefone do contato"
                                    },
                                    "contato_email": {
                                        "type": "string",
                                        "description": "E-mail do contato"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": "Observações"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Empresa ativa"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Excluir empresa",
                "description": "Remove a empresa.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Empresa excluída."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/transportes/{id}/status": {
            "patch": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Alterar status",
                "description": "Ativa ou desativa a empresa.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "ativo": false
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/transportes": {
            "get": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Listar transportes da excursão",
                "description": "Lista os transportes (veículos + vagas) configurados na excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 9,
                                            "excursao_id": 45,
                                            "veiculo_id": 5,
                                            "empresa_transporte_id": 2,
                                            "nome": "Ônibus 1",
                                            "numero": "01",
                                            "tipo": "onibus_leito",
                                            "vagas_total": 46,
                                            "vagas_reserva_admin": 2,
                                            "ordem": 0,
                                            "ativo": true,
                                            "veiculo": {
                                                "id": 5,
                                                "modelo": "Paradiso 1600 LD",
                                                "placa": "ABC-1234"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Transportes"
                ],
                "summary": "Adicionar transporte à excursão",
                "description": "Configura um veículo para a excursão com vagas.",
                "security": [
                    {
                        "bearerAuth": [
                            "transportes:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 9,
                                        "excursao_id": 45,
                                        "veiculo_id": 5
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "veiculo_id": {
                                        "type": "integer",
                                        "description": "ID do veículo"
                                    },
                                    "empresa_transporte_id": {
                                        "type": "integer",
                                        "description": "ID da empresa (default do veículo)"
                                    },
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome exibido (ex: \"Ônibus 1\")"
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Número"
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "onibus, micro_onibus, van, carro, outro"
                                    },
                                    "vagas_total": {
                                        "type": "integer",
                                        "description": "Vagas totais (>=1)"
                                    },
                                    "vagas_reserva_admin": {
                                        "type": "integer",
                                        "description": "Vagas reservadas para venda interna"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Ativo"
                                    }
                                },
                                "required": [
                                    "veiculo_id",
                                    "vagas_total"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/hospedarias": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Listar hospedarias",
                "description": "Paginada. Filtros opcionais: ativo, tipo, cidade, search.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "true|false",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "tipo",
                        "in": "query",
                        "required": false,
                        "description": "hotel|pousada|resort|hostel|chacara|camping|outro",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cidade",
                        "in": "query",
                        "required": false,
                        "description": "",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por nome",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Max 100 (default 20)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 0,
                                        "last_page": 1
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Criar hospedaria",
                "description": "Aceita criação aninhada de `tipos_quarto[]` e `suplementos[]` no mesmo payload.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Hospedaria cadastrada com sucesso.",
                                    "data": {
                                        "id": 1
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "hotel|pousada|resort|hostel|chacara|camping|outro"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF (2 letras)"
                                    },
                                    "cep": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "telefone": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "website": {
                                        "type": "string",
                                        "description": "URL"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "amenidades": {
                                        "type": "array",
                                        "description": "Ex: [\"wifi\",\"piscina\",\"cafe_manha\"]"
                                    },
                                    "politica_checkin": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "politica_checkout": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "politica_cancelamento": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    },
                                    "tipos_quarto": {
                                        "type": "array",
                                        "description": "Array de {nome, capacidade_min, capacidade_max, descricao}"
                                    },
                                    "suplementos": {
                                        "type": "array",
                                        "description": "Array de {nome, tipo, preco_padrao, cobranca}"
                                    }
                                },
                                "required": [
                                    "nome",
                                    "tipo"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/hospedarias/{id}": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Detalhes da hospedaria",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 1,
                                        "nome": "Hotel Madero",
                                        "tipo": "hotel",
                                        "tipos_quarto": [],
                                        "suplementos": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Atualizar hospedaria",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Hospedaria atualizada."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Remover hospedaria",
                "description": "Falha com 422 se houver excursões vinculadas.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Hospedaria removida."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/hospedarias/{id}/status": {
            "patch": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Toggle ativo/inativo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "ativo": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/hospedarias/{id}/tipos-quarto": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Listar tipos de quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Criar tipo de quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 5
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Ex: Standard Duplo, Suíte Master"
                                    },
                                    "capacidade_min": {
                                        "type": "integer",
                                        "description": "Min 1"
                                    },
                                    "capacidade_max": {
                                        "type": "integer",
                                        "description": "Min 1"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "amenidades": {
                                        "type": "array",
                                        "description": ""
                                    },
                                    "foto_url": {
                                        "type": "string",
                                        "description": "URL"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "nome",
                                    "capacidade_min",
                                    "capacidade_max"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/hospedarias/{id}/tipos-quarto/{tipoId}": {
            "put": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Atualizar tipo de quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "tipoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do tipo",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Remover tipo de quarto",
                "description": "Falha com 422 se houver allotment usando este tipo.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "tipoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/hospedarias/{id}/suplementos": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Listar suplementos",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Criar suplemento",
                "description": "Suplementos são extras (café reforçado, upgrade vista mar, etc) com preço padrão da hospedaria.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 3
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "tipo": {
                                        "type": "string",
                                        "description": "Tipos definidos em Suplemento::TIPOS"
                                    },
                                    "preco_padrao": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "cobranca": {
                                        "type": "string",
                                        "description": "por_pessoa|por_quarto|por_noite"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "nome",
                                    "tipo",
                                    "preco_padrao",
                                    "cobranca"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/hospedarias/{id}/suplementos/{suplementoId}": {
            "put": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Atualizar suplemento",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "suplementoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Remover suplemento",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da hospedaria",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "suplementoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Listar hospedagens da excursão",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Vincular hospedaria à excursão",
                "description": "Cria o vínculo, opcionalmente com `quartos_disponiveis[]` (allotment) e `suplementos[]` configurados pra essa excursão. Sincroniza custo com módulo financeiro.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 10
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "hospedaria_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "checkin_data": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "checkout_data": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD (após checkin)"
                                    },
                                    "checkin_hora": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "checkout_hora": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "custo_total": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "rooming_list_prazo": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "pendente|confirmado|cancelado"
                                    },
                                    "quartos_disponiveis": {
                                        "type": "array",
                                        "description": "Array de {tipo_quarto_id, quantidade, preco_por_pessoa, preco_por_quarto, custo_por_quarto, visivel_checkout}"
                                    },
                                    "suplementos": {
                                        "type": "array",
                                        "description": "Array de {suplemento_id, preco, cobranca, visivel_checkout}"
                                    }
                                },
                                "required": [
                                    "hospedaria_id",
                                    "checkin_data",
                                    "checkout_data"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/disponiveis": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Hospedarias disponíveis pra vincular",
                "description": "Lista hospedarias do tenant que ainda não estão vinculadas à excursão.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}": {
            "put": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Atualizar vínculo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Remover vínculo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/quartos": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Listar quartos do vínculo",
                "description": "Retorna os quartos criados (gerados a partir do allotment ou adicionados manualmente) com os hóspedes alocados em cada um.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "quartos": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Adicionar quarto avulso",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Quarto adicionado"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo_quarto_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "numero": {
                                        "type": "string",
                                        "description": "Identificador (ex: 101, Cabine A12)"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "tipo_quarto_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/quartos/{quartoId}": {
            "put": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Atualizar quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "quartoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Excluir quarto",
                "description": "Falha com 422 se houver hóspedes alocados (desalocar antes).",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "quartoId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/quartos/gerar": {
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Gerar quartos a partir do allotment",
                "description": "Cria quartos vazios automaticamente baseado nos `quartos_disponiveis` do vínculo.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/alocar": {
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Alocar passageiro em quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "passageiro_id": {
                                        "type": "integer",
                                        "description": "ID do ExcursaoPassageiro"
                                    },
                                    "quarto_id": {
                                        "type": "integer",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "passageiro_id",
                                    "quarto_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/desalocar": {
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Desalocar passageiro",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Passageiro removido do quarto"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "passageiro_id": {
                                        "type": "integer",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "passageiro_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/alocar-guia": {
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Alocar guia em quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "guia_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "quarto_id": {
                                        "type": "integer",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "guia_id",
                                    "quarto_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/desalocar-guia": {
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Desalocar guia",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "guia_id": {
                                        "type": "integer",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "guia_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/alocar-automaticamente": {
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Alocação automática",
                "description": "Distribui passageiros nos quartos automaticamente, respeitando capacidade e separação por gênero/grupo familiar quando aplicável.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/limpar-alocacoes": {
            "post": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Limpar todas as alocações",
                "description": "Remove todos os passageiros e guias dos quartos. Mantém os quartos criados.",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/passageiros-sem-quarto": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Passageiros sem quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "passageiros": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/excursoes/{excursaoId}/hospedagens/{vinculoId}/guias-sem-quarto": {
            "get": {
                "tags": [
                    "Hospedagem"
                ],
                "summary": "Guias sem quarto",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "hospedagem:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "excursaoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da excursão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "vinculoId",
                        "in": "path",
                        "required": true,
                        "description": "ID do vínculo excursão-hospedagem",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "guias": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/ingressos": {
            "get": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Listar ingressos",
                "description": "Paginada. Filtros: ativo, cidade, search, data_min, data_max.",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "cidade",
                        "in": "query",
                        "required": false,
                        "description": "",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por nome",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_min",
                        "in": "query",
                        "required": false,
                        "description": "Data evento mínima YYYY-MM-DD",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_max",
                        "in": "query",
                        "required": false,
                        "description": "Data evento máxima YYYY-MM-DD",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Max 100 (default 20)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [],
                                    "meta": {
                                        "total": 0
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Criar ingresso",
                "description": "Quando `tipo_venda=direta` (default), `categorias[]` é obrigatório. Quando `tipo_venda=afiliado`, `website` é obrigatório e categorias podem ser omitidas.",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Ingresso cadastrado.",
                                    "data": {
                                        "id": 1
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "local": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF (2 letras)"
                                    },
                                    "website": {
                                        "type": "string",
                                        "description": "URL — obrigatório se tipo_venda=afiliado"
                                    },
                                    "imagem_url": {
                                        "type": "string",
                                        "description": "URL"
                                    },
                                    "data_evento": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD (não pode ser passado)"
                                    },
                                    "hora_evento": {
                                        "type": "string",
                                        "description": "HH:MM"
                                    },
                                    "quantidade_total": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "quantidade_limite_venda": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": ""
                                    },
                                    "tipo_venda": {
                                        "type": "string",
                                        "description": "direta (default) | afiliado"
                                    },
                                    "categorias": {
                                        "type": "array",
                                        "description": "Array de {nome, descricao, idade_min, idade_max, preco_custo, preco_venda}. Obrigatório se tipo_venda=direta"
                                    }
                                },
                                "required": [
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/ingressos/{id}": {
            "get": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Detalhes do ingresso",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 1,
                                        "nome": "Show da banda X",
                                        "categorias": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Atualizar ingresso",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Ingresso atualizado."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": ""
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Remover ingresso",
                "description": "Falha com 422 se houver vendas registradas.",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/ingressos/{id}/status": {
            "patch": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Toggle ativo/inativo",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "ativo": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/ingressos/{id}/categorias": {
            "get": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Listar categorias",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Criar categoria (tipo de ingresso)",
                "description": "Ex: Inteira, Meia, Idoso, Estudante. Cada categoria tem preço de custo e venda.",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 1
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Ex: Inteira, Meia, Idoso"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "idade_min": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "idade_max": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "preco_custo": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "preco_venda": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": ""
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": ""
                                    }
                                },
                                "required": [
                                    "nome",
                                    "preco_custo",
                                    "preco_venda"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/ingressos/{id}/categorias/{categoriaId}": {
            "put": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Atualizar categoria",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "categoriaId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Remover categoria",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "categoriaId",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/ingressos/{id}/estoque": {
            "get": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Listar estoque por data",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "data_min",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_max",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Definir/atualizar estoque de uma data",
                "description": "Upsert por (ingresso_id, data). Para alterar várias datas chame múltiplas vezes.",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do ingresso",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Estoque atualizado."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "data": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "quantidade_total": {
                                        "type": "integer",
                                        "description": "Estoque total para essa data"
                                    },
                                    "disponivel": {
                                        "type": "boolean",
                                        "description": "Liga/desliga venda nessa data"
                                    }
                                },
                                "required": [
                                    "data",
                                    "quantidade_total"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/ingressos/vendas": {
            "get": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Listar vendas",
                "description": "Paginada. Filtros: ingresso_id, status, data_min, data_max.",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "ingresso_id",
                        "in": "query",
                        "required": false,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "pendente|pago|cancelado|usado",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_min",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_max",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Registrar venda manual",
                "description": "Registra venda manualmente (ex: vendido no balcão). `valor_total` é calculado automaticamente como `quantidade * valor_unitario - desconto`.",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Venda registrada.",
                                    "data": {
                                        "id": 100
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ingresso_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "categoria_id": {
                                        "type": "integer",
                                        "description": ""
                                    },
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "Se cliente já cadastrado"
                                    },
                                    "comprador_nome": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "comprador_cpf": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "comprador_email": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "comprador_telefone": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "quantidade": {
                                        "type": "integer",
                                        "description": "Min 1"
                                    },
                                    "valor_unitario": {
                                        "type": "number",
                                        "description": ""
                                    },
                                    "desconto": {
                                        "type": "number",
                                        "description": "Default 0"
                                    },
                                    "forma_pagamento": {
                                        "type": "string",
                                        "description": "pix|dinheiro|cartao|..."
                                    },
                                    "data_uso": {
                                        "type": "string",
                                        "description": "YYYY-MM-DD"
                                    },
                                    "observacoes": {
                                        "type": "string",
                                        "description": ""
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "pendente (default) | pago | cancelado | usado"
                                    }
                                },
                                "required": [
                                    "ingresso_id",
                                    "categoria_id",
                                    "comprador_nome",
                                    "quantidade",
                                    "valor_unitario"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/ingressos/vendas/{id}": {
            "get": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Detalhes da venda",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 100,
                                        "status": "pago"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/ingressos/vendas/{id}/status": {
            "patch": {
                "tags": [
                    "Ingressos"
                ],
                "summary": "Atualizar status da venda",
                "description": "",
                "security": [
                    {
                        "bearerAuth": [
                            "ingressos:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "description": "pendente | pago | cancelado | usado"
                                    }
                                },
                                "required": [
                                    "status"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar passeios",
                "description": "Lista paginada do catálogo, com a contagem de categorias, horários, extras e vendas de cada passeio.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Número da página",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens por página (max: 100)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "ativo",
                        "in": "query",
                        "required": false,
                        "description": "Filtra por disponível para venda",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "destaque",
                        "in": "query",
                        "required": false,
                        "description": "Somente destacados",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "mostrar_site",
                        "in": "query",
                        "required": false,
                        "description": "Somente os publicados no site",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "rascunho ou publicado",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cidade",
                        "in": "query",
                        "required": false,
                        "description": "Busca parcial por cidade",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "estado",
                        "in": "query",
                        "required": false,
                        "description": "UF exata",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "pais",
                        "in": "query",
                        "required": false,
                        "description": "País exato",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "categoria_tipo",
                        "in": "query",
                        "required": false,
                        "description": "Tipo do passeio",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "dificuldade",
                        "in": "query",
                        "required": false,
                        "description": "Nível de dificuldade",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca em nome, descrição curta e local",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "description": "Sub-recursos no mesmo payload: categorias, horarios, extras, temporadas, fotos (separados por vírgula)",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 12,
                                            "nome": "Trilha da Pedra Bonita ao amanhecer",
                                            "slug": "trilha-pedra-bonita-amanhecer",
                                            "descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
                                            "local": "Parque Nacional da Tijuca",
                                            "cidade": "Rio de Janeiro",
                                            "estado": "RJ",
                                            "pais": "Brasil",
                                            "ponto_encontro": "Estacionamento da Pedra Bonita",
                                            "latitude": -22.9871234,
                                            "longitude": -43.2812345,
                                            "duracao_minutos": 180,
                                            "dificuldade": "moderado",
                                            "idade_minima": 12,
                                            "capacidade_maxima": 20,
                                            "antecedencia_minima_horas": 12,
                                            "cancelamento_horas": 24,
                                            "reembolso_percentual": 100,
                                            "exigir_waiver": true,
                                            "mostrar_site": true,
                                            "ativo": true,
                                            "status": "publicado",
                                            "categorias_count": 2,
                                            "horarios_count": 3,
                                            "extras_count": 1,
                                            "vendas_count": 47
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Criar passeio",
                "description": "Cria um passeio. Aceita as categorias no mesmo payload, porque passeio sem categoria não vende. O slug é gerado a partir do nome quando não informado.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Passeio criado com sucesso",
                                    "data": {
                                        "id": 12,
                                        "nome": "Trilha da Pedra Bonita ao amanhecer",
                                        "slug": "trilha-pedra-bonita-amanhecer",
                                        "descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
                                        "local": "Parque Nacional da Tijuca",
                                        "cidade": "Rio de Janeiro",
                                        "estado": "RJ",
                                        "pais": "Brasil",
                                        "ponto_encontro": "Estacionamento da Pedra Bonita",
                                        "latitude": -22.9871234,
                                        "longitude": -43.2812345,
                                        "duracao_minutos": 180,
                                        "dificuldade": "moderado",
                                        "idade_minima": 12,
                                        "capacidade_maxima": 20,
                                        "antecedencia_minima_horas": 12,
                                        "cancelamento_horas": 24,
                                        "reembolso_percentual": 100,
                                        "exigir_waiver": true,
                                        "mostrar_site": true,
                                        "ativo": true,
                                        "status": "publicado",
                                        "categorias_count": 2,
                                        "horarios_count": 3,
                                        "extras_count": 1,
                                        "vendas_count": 47
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do passeio"
                                    },
                                    "slug": {
                                        "type": "string",
                                        "description": "URL amigável. Gerado a partir do nome quando omitido. Único por tenant"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição completa (HTML permitido)"
                                    },
                                    "descricao_curta": {
                                        "type": "string",
                                        "description": "Resumo usado em listagens e cards"
                                    },
                                    "o_que_inclui": {
                                        "type": "string",
                                        "description": "O que está incluído no valor"
                                    },
                                    "o_que_nao_inclui": {
                                        "type": "string",
                                        "description": "O que não está incluído"
                                    },
                                    "o_que_levar": {
                                        "type": "string",
                                        "description": "Itens que o cliente deve levar"
                                    },
                                    "dicas": {
                                        "type": "string",
                                        "description": "Dicas para o participante"
                                    },
                                    "requisitos": {
                                        "type": "string",
                                        "description": "Requisitos de saúde, físicos ou documentais"
                                    },
                                    "local": {
                                        "type": "string",
                                        "description": "Local do passeio"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço completo"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF (2 letras)"
                                    },
                                    "pais": {
                                        "type": "string",
                                        "description": "País"
                                    },
                                    "continente": {
                                        "type": "string",
                                        "description": "Continente"
                                    },
                                    "destino_slug": {
                                        "type": "string",
                                        "description": "Slug do destino, para agrupar passeios da mesma região"
                                    },
                                    "ponto_encontro": {
                                        "type": "string",
                                        "description": "Onde o grupo se encontra"
                                    },
                                    "ponto_encontro_maps": {
                                        "type": "string",
                                        "description": "Link do Google Maps do ponto de encontro"
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude (-90 a 90)"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude (-180 a 180)"
                                    },
                                    "imagem": {
                                        "type": "string",
                                        "description": "URL da imagem de capa"
                                    },
                                    "videos": {
                                        "type": "array",
                                        "description": "Lista de URLs de vídeo"
                                    },
                                    "duracao_minutos": {
                                        "type": "integer",
                                        "description": "Duração em minutos"
                                    },
                                    "dificuldade": {
                                        "type": "string",
                                        "description": "Nível de dificuldade (facil, moderado, dificil)"
                                    },
                                    "idade_minima": {
                                        "type": "integer",
                                        "description": "Idade mínima permitida"
                                    },
                                    "capacidade_maxima": {
                                        "type": "integer",
                                        "description": "Capacidade máxima por saída"
                                    },
                                    "categoria_tipo": {
                                        "type": "string",
                                        "description": "Tipo do passeio (aventura, cultural, gastronomico...)"
                                    },
                                    "antecedencia_minima_horas": {
                                        "type": "integer",
                                        "description": "Antecedência mínima para reservar"
                                    },
                                    "cancelamento_horas": {
                                        "type": "integer",
                                        "description": "Prazo em horas para cancelar com reembolso"
                                    },
                                    "reembolso_percentual": {
                                        "type": "integer",
                                        "description": "Percentual reembolsado dentro do prazo (0 a 100)"
                                    },
                                    "permitir_reagendamento": {
                                        "type": "boolean",
                                        "description": "Permite remarcar a data"
                                    },
                                    "exigir_waiver": {
                                        "type": "boolean",
                                        "description": "Exige termo de responsabilidade assinado"
                                    },
                                    "mostrar_site": {
                                        "type": "boolean",
                                        "description": "Aparece no site público"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Disponível para venda (default true)"
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": "Destacado nas listagens"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "rascunho ou publicado"
                                    },
                                    "banner_display_mode": {
                                        "type": "string",
                                        "description": "Como a capa é exibida no site"
                                    },
                                    "meta_title": {
                                        "type": "string",
                                        "description": "Título para SEO"
                                    },
                                    "meta_description": {
                                        "type": "string",
                                        "description": "Descrição para SEO"
                                    },
                                    "meta_keywords": {
                                        "type": "string",
                                        "description": "Palavras-chave para SEO"
                                    },
                                    "observacoes_internas": {
                                        "type": "string",
                                        "description": "Notas internas, não exibidas ao cliente"
                                    },
                                    "preco_display_modo": {
                                        "type": "string",
                                        "description": "Como o preço aparece no site"
                                    },
                                    "preco_display_intervalo": {
                                        "type": "boolean",
                                        "description": "Exibe faixa de preço em vez de valor único"
                                    },
                                    "modo_preco": {
                                        "type": "string",
                                        "description": "Modo de precificação"
                                    },
                                    "seguro_link": {
                                        "type": "string",
                                        "description": "Link da apólice de seguro"
                                    },
                                    "seguro_label": {
                                        "type": "string",
                                        "description": "Texto do botão de seguro"
                                    },
                                    "badge_sazonalidade": {
                                        "type": "string",
                                        "description": "Selo de sazonalidade exibido no card"
                                    },
                                    "tags_categorias": {
                                        "type": "array",
                                        "description": "Tags livres de categorização"
                                    },
                                    "import_source": {
                                        "type": "string",
                                        "description": "Origem, quando importado de outro sistema"
                                    },
                                    "import_external_id": {
                                        "type": "string",
                                        "description": "ID no sistema de origem"
                                    },
                                    "categorias": {
                                        "type": "array",
                                        "description": "Categorias criadas junto com o passeio (apenas no POST). Cada item aceita nome, preco_venda, preco_custo, idade_min, idade_max, conta_como, ordem"
                                    }
                                },
                                "required": [
                                    "nome"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/{id}": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Detalhar passeio",
                "description": "Retorna o passeio com categorias, horários, extras, temporadas e fotos já carregados.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 12,
                                        "nome": "Trilha da Pedra Bonita ao amanhecer",
                                        "slug": "trilha-pedra-bonita-amanhecer",
                                        "descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
                                        "local": "Parque Nacional da Tijuca",
                                        "cidade": "Rio de Janeiro",
                                        "estado": "RJ",
                                        "pais": "Brasil",
                                        "ponto_encontro": "Estacionamento da Pedra Bonita",
                                        "latitude": -22.9871234,
                                        "longitude": -43.2812345,
                                        "duracao_minutos": 180,
                                        "dificuldade": "moderado",
                                        "idade_minima": 12,
                                        "capacidade_maxima": 20,
                                        "antecedencia_minima_horas": 12,
                                        "cancelamento_horas": 24,
                                        "reembolso_percentual": 100,
                                        "exigir_waiver": true,
                                        "mostrar_site": true,
                                        "ativo": true,
                                        "status": "publicado",
                                        "categorias_count": 2,
                                        "horarios_count": 3,
                                        "extras_count": 1,
                                        "vendas_count": 47,
                                        "categorias": [
                                            {
                                                "id": 30,
                                                "passeio_id": 12,
                                                "nome": "Adulto",
                                                "descricao": "A partir de 12 anos",
                                                "preco_custo": 40,
                                                "preco_venda": 120,
                                                "idade_min": 12,
                                                "idade_max": null,
                                                "conta_como": "pessoa",
                                                "estoque_consome": 1,
                                                "ativo": true,
                                                "ordem": 0
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Atualizar passeio",
                "description": "Atualização parcial: envie apenas os campos que quer mudar.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Passeio atualizado com sucesso",
                                    "data": {
                                        "id": 12,
                                        "nome": "Trilha da Pedra Bonita ao amanhecer",
                                        "slug": "trilha-pedra-bonita-amanhecer",
                                        "descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
                                        "local": "Parque Nacional da Tijuca",
                                        "cidade": "Rio de Janeiro",
                                        "estado": "RJ",
                                        "pais": "Brasil",
                                        "ponto_encontro": "Estacionamento da Pedra Bonita",
                                        "latitude": -22.9871234,
                                        "longitude": -43.2812345,
                                        "duracao_minutos": 180,
                                        "dificuldade": "moderado",
                                        "idade_minima": 12,
                                        "capacidade_maxima": 20,
                                        "antecedencia_minima_horas": 12,
                                        "cancelamento_horas": 24,
                                        "reembolso_percentual": 100,
                                        "exigir_waiver": true,
                                        "mostrar_site": true,
                                        "ativo": true,
                                        "status": "publicado",
                                        "categorias_count": 2,
                                        "horarios_count": 3,
                                        "extras_count": 1,
                                        "vendas_count": 47
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do passeio"
                                    },
                                    "slug": {
                                        "type": "string",
                                        "description": "URL amigável. Gerado a partir do nome quando omitido. Único por tenant"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Descrição completa (HTML permitido)"
                                    },
                                    "descricao_curta": {
                                        "type": "string",
                                        "description": "Resumo usado em listagens e cards"
                                    },
                                    "o_que_inclui": {
                                        "type": "string",
                                        "description": "O que está incluído no valor"
                                    },
                                    "o_que_nao_inclui": {
                                        "type": "string",
                                        "description": "O que não está incluído"
                                    },
                                    "o_que_levar": {
                                        "type": "string",
                                        "description": "Itens que o cliente deve levar"
                                    },
                                    "dicas": {
                                        "type": "string",
                                        "description": "Dicas para o participante"
                                    },
                                    "requisitos": {
                                        "type": "string",
                                        "description": "Requisitos de saúde, físicos ou documentais"
                                    },
                                    "local": {
                                        "type": "string",
                                        "description": "Local do passeio"
                                    },
                                    "endereco": {
                                        "type": "string",
                                        "description": "Endereço completo"
                                    },
                                    "cidade": {
                                        "type": "string",
                                        "description": "Cidade"
                                    },
                                    "estado": {
                                        "type": "string",
                                        "description": "UF (2 letras)"
                                    },
                                    "pais": {
                                        "type": "string",
                                        "description": "País"
                                    },
                                    "continente": {
                                        "type": "string",
                                        "description": "Continente"
                                    },
                                    "destino_slug": {
                                        "type": "string",
                                        "description": "Slug do destino, para agrupar passeios da mesma região"
                                    },
                                    "ponto_encontro": {
                                        "type": "string",
                                        "description": "Onde o grupo se encontra"
                                    },
                                    "ponto_encontro_maps": {
                                        "type": "string",
                                        "description": "Link do Google Maps do ponto de encontro"
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude (-90 a 90)"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude (-180 a 180)"
                                    },
                                    "imagem": {
                                        "type": "string",
                                        "description": "URL da imagem de capa"
                                    },
                                    "videos": {
                                        "type": "array",
                                        "description": "Lista de URLs de vídeo"
                                    },
                                    "duracao_minutos": {
                                        "type": "integer",
                                        "description": "Duração em minutos"
                                    },
                                    "dificuldade": {
                                        "type": "string",
                                        "description": "Nível de dificuldade (facil, moderado, dificil)"
                                    },
                                    "idade_minima": {
                                        "type": "integer",
                                        "description": "Idade mínima permitida"
                                    },
                                    "capacidade_maxima": {
                                        "type": "integer",
                                        "description": "Capacidade máxima por saída"
                                    },
                                    "categoria_tipo": {
                                        "type": "string",
                                        "description": "Tipo do passeio (aventura, cultural, gastronomico...)"
                                    },
                                    "antecedencia_minima_horas": {
                                        "type": "integer",
                                        "description": "Antecedência mínima para reservar"
                                    },
                                    "cancelamento_horas": {
                                        "type": "integer",
                                        "description": "Prazo em horas para cancelar com reembolso"
                                    },
                                    "reembolso_percentual": {
                                        "type": "integer",
                                        "description": "Percentual reembolsado dentro do prazo (0 a 100)"
                                    },
                                    "permitir_reagendamento": {
                                        "type": "boolean",
                                        "description": "Permite remarcar a data"
                                    },
                                    "exigir_waiver": {
                                        "type": "boolean",
                                        "description": "Exige termo de responsabilidade assinado"
                                    },
                                    "mostrar_site": {
                                        "type": "boolean",
                                        "description": "Aparece no site público"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Disponível para venda (default true)"
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": "Destacado nas listagens"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "rascunho ou publicado"
                                    },
                                    "banner_display_mode": {
                                        "type": "string",
                                        "description": "Como a capa é exibida no site"
                                    },
                                    "meta_title": {
                                        "type": "string",
                                        "description": "Título para SEO"
                                    },
                                    "meta_description": {
                                        "type": "string",
                                        "description": "Descrição para SEO"
                                    },
                                    "meta_keywords": {
                                        "type": "string",
                                        "description": "Palavras-chave para SEO"
                                    },
                                    "observacoes_internas": {
                                        "type": "string",
                                        "description": "Notas internas, não exibidas ao cliente"
                                    },
                                    "preco_display_modo": {
                                        "type": "string",
                                        "description": "Como o preço aparece no site"
                                    },
                                    "preco_display_intervalo": {
                                        "type": "boolean",
                                        "description": "Exibe faixa de preço em vez de valor único"
                                    },
                                    "modo_preco": {
                                        "type": "string",
                                        "description": "Modo de precificação"
                                    },
                                    "seguro_link": {
                                        "type": "string",
                                        "description": "Link da apólice de seguro"
                                    },
                                    "seguro_label": {
                                        "type": "string",
                                        "description": "Texto do botão de seguro"
                                    },
                                    "badge_sazonalidade": {
                                        "type": "string",
                                        "description": "Selo de sazonalidade exibido no card"
                                    },
                                    "tags_categorias": {
                                        "type": "array",
                                        "description": "Tags livres de categorização"
                                    },
                                    "import_source": {
                                        "type": "string",
                                        "description": "Origem, quando importado de outro sistema"
                                    },
                                    "import_external_id": {
                                        "type": "string",
                                        "description": "ID no sistema de origem"
                                    },
                                    "categorias": {
                                        "type": "array",
                                        "description": "Categorias criadas junto com o passeio (apenas no POST). Cada item aceita nome, preco_venda, preco_custo, idade_min, idade_max, conta_como, ordem"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Excluir passeio",
                "description": "Remove o passeio e seus sub-recursos. Bloqueado com 422 quando já há vendas registradas (PASSEIO_COM_VENDAS): nesse caso use ativo=false, que tira da venda sem apagar histórico.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Passeio removido com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/{id}/status": {
            "patch": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Ligar ou desligar passeio",
                "description": "Atalho para mudar ativo, mostrar_site, destaque ou status sem enviar o cadastro inteiro.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Status atualizado"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Disponível para venda"
                                    },
                                    "mostrar_site": {
                                        "type": "boolean",
                                        "description": "Aparece no site"
                                    },
                                    "destaque": {
                                        "type": "boolean",
                                        "description": "Destacado"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "rascunho ou publicado"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/passeios/{id}/categorias": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar categorias",
                "description": "Tipos de bilhete do passeio (Adulto, Criança, Meia), com preço de custo e de venda.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 30,
                                            "passeio_id": 12,
                                            "nome": "Adulto",
                                            "descricao": "A partir de 12 anos",
                                            "preco_custo": 40,
                                            "preco_venda": 120,
                                            "idade_min": 12,
                                            "idade_max": null,
                                            "conta_como": "pessoa",
                                            "estoque_consome": 1,
                                            "ativo": true,
                                            "ordem": 0
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Criar categoria",
                "description": "Tipos de bilhete do passeio (Adulto, Criança, Meia), com preço de custo e de venda.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Categoria criada com sucesso",
                                    "data": {
                                        "id": 30,
                                        "passeio_id": 12,
                                        "nome": "Adulto",
                                        "descricao": "A partir de 12 anos",
                                        "preco_custo": 40,
                                        "preco_venda": 120,
                                        "idade_min": 12,
                                        "idade_max": null,
                                        "conta_como": "pessoa",
                                        "estoque_consome": 1,
                                        "ativo": true,
                                        "ordem": 0
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome da categoria (Adulto, Criança, Meia...)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Detalhamento da regra"
                                    },
                                    "preco_venda": {
                                        "type": "number",
                                        "description": "Valor cobrado do cliente"
                                    },
                                    "preco_custo": {
                                        "type": "number",
                                        "description": "Custo do fornecedor, usado no cálculo de lucro"
                                    },
                                    "idade_min": {
                                        "type": "integer",
                                        "description": "Idade mínima"
                                    },
                                    "idade_max": {
                                        "type": "integer",
                                        "description": "Idade máxima"
                                    },
                                    "conta_como": {
                                        "type": "string",
                                        "description": "Como conta na capacidade (pessoa, meia, cortesia)"
                                    },
                                    "estoque_id": {
                                        "type": "integer",
                                        "description": "Estoque compartilhado, quando houver"
                                    },
                                    "estoque_consome": {
                                        "type": "integer",
                                        "description": "Quantas vagas cada unidade consome"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Disponível para venda"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    }
                                },
                                "required": [
                                    "nome",
                                    "preco_venda"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/{id}/categorias/{categoriaId}": {
            "put": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Atualizar categoria",
                "description": "Atualização parcial: envie apenas os campos que quer mudar.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "categoriaId",
                        "in": "path",
                        "required": true,
                        "description": "ID da categoria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Categoria atualizada com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome da categoria (Adulto, Criança, Meia...)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Detalhamento da regra"
                                    },
                                    "preco_venda": {
                                        "type": "number",
                                        "description": "Valor cobrado do cliente"
                                    },
                                    "preco_custo": {
                                        "type": "number",
                                        "description": "Custo do fornecedor, usado no cálculo de lucro"
                                    },
                                    "idade_min": {
                                        "type": "integer",
                                        "description": "Idade mínima"
                                    },
                                    "idade_max": {
                                        "type": "integer",
                                        "description": "Idade máxima"
                                    },
                                    "conta_como": {
                                        "type": "string",
                                        "description": "Como conta na capacidade (pessoa, meia, cortesia)"
                                    },
                                    "estoque_id": {
                                        "type": "integer",
                                        "description": "Estoque compartilhado, quando houver"
                                    },
                                    "estoque_consome": {
                                        "type": "integer",
                                        "description": "Quantas vagas cada unidade consome"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Disponível para venda"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Excluir categoria",
                "description": "Bloqueado com 422 quando a categoria já tem vendas (RECURSO_EM_USO): nesse caso use ativo=false.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "categoriaId",
                        "in": "path",
                        "required": true,
                        "description": "ID da categoria",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Categoria removida com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/{id}/horarios": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar horarios",
                "description": "Grade de saídas: recorrente por dia da semana, diária ou em data específica.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 55,
                                            "passeio_id": 12,
                                            "tipo_recorrencia": "semanal",
                                            "dias_semana": [
                                                6,
                                                0
                                            ],
                                            "horario_inicio": "05:30",
                                            "horario_fim": "08:30",
                                            "vagas": 20,
                                            "ativo": true
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Criar horario",
                "description": "Grade de saídas: recorrente por dia da semana, diária ou em data específica.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Horário criada com sucesso",
                                    "data": {
                                        "id": 55,
                                        "passeio_id": 12,
                                        "tipo_recorrencia": "semanal",
                                        "dias_semana": [
                                            6,
                                            0
                                        ],
                                        "horario_inicio": "05:30",
                                        "horario_fim": "08:30",
                                        "vagas": 20,
                                        "ativo": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo_recorrencia": {
                                        "type": "string",
                                        "description": "semanal, diario ou data_especifica"
                                    },
                                    "dias_semana": {
                                        "type": "array",
                                        "description": "Dias da semana quando semanal (0=domingo a 6=sábado)"
                                    },
                                    "data_especifica": {
                                        "type": "string",
                                        "description": "Data única quando tipo_recorrencia=data_especifica"
                                    },
                                    "horario_inicio": {
                                        "type": "string",
                                        "description": "Hora de início (HH:MM)"
                                    },
                                    "horario_fim": {
                                        "type": "string",
                                        "description": "Hora de término (HH:MM)"
                                    },
                                    "vagas": {
                                        "type": "integer",
                                        "description": "Vagas desta saída. Sem valor usa a capacidade do passeio"
                                    },
                                    "vigencia_inicio": {
                                        "type": "string",
                                        "description": "A partir de quando a grade vale"
                                    },
                                    "vigencia_fim": {
                                        "type": "string",
                                        "description": "Até quando a grade vale"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Horário ativo"
                                    }
                                },
                                "required": [
                                    "tipo_recorrencia",
                                    "horario_inicio"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/{id}/horarios/{horarioId}": {
            "put": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Atualizar horario",
                "description": "Atualização parcial: envie apenas os campos que quer mudar.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "horarioId",
                        "in": "path",
                        "required": true,
                        "description": "ID da horario",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Horário atualizada com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "tipo_recorrencia": {
                                        "type": "string",
                                        "description": "semanal, diario ou data_especifica"
                                    },
                                    "dias_semana": {
                                        "type": "array",
                                        "description": "Dias da semana quando semanal (0=domingo a 6=sábado)"
                                    },
                                    "data_especifica": {
                                        "type": "string",
                                        "description": "Data única quando tipo_recorrencia=data_especifica"
                                    },
                                    "horario_inicio": {
                                        "type": "string",
                                        "description": "Hora de início (HH:MM)"
                                    },
                                    "horario_fim": {
                                        "type": "string",
                                        "description": "Hora de término (HH:MM)"
                                    },
                                    "vagas": {
                                        "type": "integer",
                                        "description": "Vagas desta saída. Sem valor usa a capacidade do passeio"
                                    },
                                    "vigencia_inicio": {
                                        "type": "string",
                                        "description": "A partir de quando a grade vale"
                                    },
                                    "vigencia_fim": {
                                        "type": "string",
                                        "description": "Até quando a grade vale"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Horário ativo"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Excluir horario",
                "description": "Remove o registro.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "horarioId",
                        "in": "path",
                        "required": true,
                        "description": "ID da horario",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Horário removida com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/{id}/extras": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar extras",
                "description": "Itens opcionais vendidos junto com o passeio.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 8,
                                            "passeio_id": 12,
                                            "nome": "Transfer hotel",
                                            "preco": 30,
                                            "tipo_cobranca": "por_pessoa",
                                            "quantidade_maxima": 4,
                                            "ativo": true,
                                            "ordem": 0
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Criar extra",
                "description": "Itens opcionais vendidos junto com o passeio.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Extra criada com sucesso",
                                    "data": {
                                        "id": 8,
                                        "passeio_id": 12,
                                        "nome": "Transfer hotel",
                                        "preco": 30,
                                        "tipo_cobranca": "por_pessoa",
                                        "quantidade_maxima": 4,
                                        "ativo": true,
                                        "ordem": 0
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do item opcional (transfer, almoço, foto)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Detalhamento"
                                    },
                                    "preco": {
                                        "type": "number",
                                        "description": "Valor do extra"
                                    },
                                    "tipo_cobranca": {
                                        "type": "string",
                                        "description": "por_pessoa ou por_reserva"
                                    },
                                    "quantidade_maxima": {
                                        "type": "integer",
                                        "description": "Limite por reserva"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Disponível"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    }
                                },
                                "required": [
                                    "nome",
                                    "preco"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/{id}/extras/{extraId}": {
            "put": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Atualizar extra",
                "description": "Atualização parcial: envie apenas os campos que quer mudar.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "extraId",
                        "in": "path",
                        "required": true,
                        "description": "ID da extra",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Extra atualizada com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do item opcional (transfer, almoço, foto)"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Detalhamento"
                                    },
                                    "preco": {
                                        "type": "number",
                                        "description": "Valor do extra"
                                    },
                                    "tipo_cobranca": {
                                        "type": "string",
                                        "description": "por_pessoa ou por_reserva"
                                    },
                                    "quantidade_maxima": {
                                        "type": "integer",
                                        "description": "Limite por reserva"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Disponível"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Excluir extra",
                "description": "Remove o registro.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "extraId",
                        "in": "path",
                        "required": true,
                        "description": "ID da extra",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Extra removida com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/{id}/temporadas": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar temporadas",
                "description": "Ajuste de preço por período. Quando dois períodos se sobrepõem, vence a maior prioridade.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 3,
                                            "passeio_id": 12,
                                            "nome": "Alta temporada",
                                            "data_inicio": "2026-12-20",
                                            "data_fim": "2027-01-31",
                                            "tipo_ajuste": "percentual",
                                            "valor_ajuste": 20,
                                            "prioridade": 1,
                                            "ativo": true
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Criar temporada",
                "description": "Ajuste de preço por período. Quando dois períodos se sobrepõem, vence a maior prioridade.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Temporada criada com sucesso",
                                    "data": {
                                        "id": 3,
                                        "passeio_id": 12,
                                        "nome": "Alta temporada",
                                        "data_inicio": "2026-12-20",
                                        "data_fim": "2027-01-31",
                                        "tipo_ajuste": "percentual",
                                        "valor_ajuste": 20,
                                        "prioridade": 1,
                                        "ativo": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do período (Alta temporada, Feriado)"
                                    },
                                    "data_inicio": {
                                        "type": "string",
                                        "description": "Início do período"
                                    },
                                    "data_fim": {
                                        "type": "string",
                                        "description": "Fim do período"
                                    },
                                    "tipo_ajuste": {
                                        "type": "string",
                                        "description": "percentual, valor_fixo ou preco_fixo"
                                    },
                                    "valor_ajuste": {
                                        "type": "number",
                                        "description": "Valor do ajuste conforme o tipo"
                                    },
                                    "prioridade": {
                                        "type": "integer",
                                        "description": "Quando dois períodos se sobrepõem, vence a maior prioridade"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Temporada ativa"
                                    }
                                },
                                "required": [
                                    "nome",
                                    "data_inicio",
                                    "data_fim",
                                    "tipo_ajuste",
                                    "valor_ajuste"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/{id}/temporadas/{temporadaId}": {
            "put": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Atualizar temporada",
                "description": "Atualização parcial: envie apenas os campos que quer mudar.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "temporadaId",
                        "in": "path",
                        "required": true,
                        "description": "ID da temporada",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Temporada atualizada com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "nome": {
                                        "type": "string",
                                        "description": "Nome do período (Alta temporada, Feriado)"
                                    },
                                    "data_inicio": {
                                        "type": "string",
                                        "description": "Início do período"
                                    },
                                    "data_fim": {
                                        "type": "string",
                                        "description": "Fim do período"
                                    },
                                    "tipo_ajuste": {
                                        "type": "string",
                                        "description": "percentual, valor_fixo ou preco_fixo"
                                    },
                                    "valor_ajuste": {
                                        "type": "number",
                                        "description": "Valor do ajuste conforme o tipo"
                                    },
                                    "prioridade": {
                                        "type": "integer",
                                        "description": "Quando dois períodos se sobrepõem, vence a maior prioridade"
                                    },
                                    "ativo": {
                                        "type": "boolean",
                                        "description": "Temporada ativa"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Excluir temporada",
                "description": "Remove o registro.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "temporadaId",
                        "in": "path",
                        "required": true,
                        "description": "ID da temporada",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Temporada removida com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/{id}/fotos": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar fotos",
                "description": "Galeria do passeio, na ordem de exibição.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 71,
                                            "passeio_id": 12,
                                            "url": "https://cdn.exemplo.com/foto.jpg",
                                            "titulo": "Vista do topo",
                                            "ordem": 0
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Adicionar foto",
                "description": "Adiciona uma foto por URL. O arquivo deve estar hospedado pelo integrador.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Foto criada com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "description": "URL da imagem"
                                    },
                                    "thumbnail_url": {
                                        "type": "string",
                                        "description": "URL da miniatura"
                                    },
                                    "titulo": {
                                        "type": "string",
                                        "description": "Título da foto"
                                    },
                                    "descricao": {
                                        "type": "string",
                                        "description": "Legenda"
                                    },
                                    "ordem": {
                                        "type": "integer",
                                        "description": "Ordem de exibição"
                                    }
                                },
                                "required": [
                                    "url"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/{id}/fotos/{fotoId}": {
            "delete": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Remover foto",
                "description": "Remove a foto da galeria.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:delete"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "fotoId",
                        "in": "path",
                        "required": true,
                        "description": "ID da foto",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Foto removida com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/vendas": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar vendas",
                "description": "Lista paginada das vendas, com passeio, categoria, cliente e a contagem de itens do voucher.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Número da página",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens por página (max: 100)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "passeio_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtra por passeio",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "cliente_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtra por cliente",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sessao_id",
                        "in": "query",
                        "required": false,
                        "description": "Filtra por sessão",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "reservado, confirmado, usado ou cancelado",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "checked_in",
                        "in": "query",
                        "required": false,
                        "description": "Somente com ou sem check-in",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "origem",
                        "in": "query",
                        "required": false,
                        "description": "Canal da venda",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "codigo_voucher",
                        "in": "query",
                        "required": false,
                        "description": "Código do voucher da venda (case-insensitive)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_de",
                        "in": "query",
                        "required": false,
                        "description": "Data inicial da sessão",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "data_ate",
                        "in": "query",
                        "required": false,
                        "description": "Data final da sessão",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Busca por nome ou documento do beneficiário",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 508,
                                            "uuid": "3f1c0a2e-8b4d-4f6a-9c11-2d7e5a9b0c33",
                                            "passeio_id": 12,
                                            "categoria_id": 30,
                                            "cliente_id": 91,
                                            "beneficiario_nome": "Marina Torres",
                                            "beneficiario_documento": "123.456.789-00",
                                            "quantidade": 2,
                                            "valor_unitario": 120,
                                            "valor_extras": 30,
                                            "desconto": 0,
                                            "valor_total": 270,
                                            "status": "confirmado",
                                            "codigo_voucher": "K7PJ4RQ2",
                                            "checked_in": false,
                                            "origem": "api",
                                            "voucher_items_count": 2
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Registrar venda",
                "description": "Registra uma venda e gera o código do voucher. Sem valor_unitario, usa o preco_venda da categoria, para o integrador não precisar replicar a tabela de preços. Recusa com 422 quando a categoria não pertence ao passeio (CATEGORIA_DE_OUTRO_PASSEIO) ou quando o desconto deixa o total negativo (TOTAL_NEGATIVO).",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Venda registrada com sucesso",
                                    "data": {
                                        "id": 508,
                                        "uuid": "3f1c0a2e-8b4d-4f6a-9c11-2d7e5a9b0c33",
                                        "passeio_id": 12,
                                        "categoria_id": 30,
                                        "cliente_id": 91,
                                        "beneficiario_nome": "Marina Torres",
                                        "beneficiario_documento": "123.456.789-00",
                                        "quantidade": 2,
                                        "valor_unitario": 120,
                                        "valor_extras": 30,
                                        "desconto": 0,
                                        "valor_total": 270,
                                        "status": "confirmado",
                                        "codigo_voucher": "K7PJ4RQ2",
                                        "checked_in": false,
                                        "origem": "api",
                                        "voucher_items_count": 2
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "passeio_id": {
                                        "type": "integer",
                                        "description": "ID do passeio"
                                    },
                                    "categoria_id": {
                                        "type": "integer",
                                        "description": "ID da categoria. Precisa pertencer ao passeio informado"
                                    },
                                    "sessao_id": {
                                        "type": "integer",
                                        "description": "Sessão (data e hora) escolhida"
                                    },
                                    "cliente_id": {
                                        "type": "integer",
                                        "description": "Cliente cadastrado, quando houver"
                                    },
                                    "beneficiario_nome": {
                                        "type": "string",
                                        "description": "Nome de quem vai fazer o passeio"
                                    },
                                    "beneficiario_documento": {
                                        "type": "string",
                                        "description": "CPF ou documento"
                                    },
                                    "beneficiario_telefone": {
                                        "type": "string",
                                        "description": "Telefone de contato"
                                    },
                                    "quantidade": {
                                        "type": "integer",
                                        "description": "Quantidade de pessoas. Gera um item de voucher para cada"
                                    },
                                    "valor_unitario": {
                                        "type": "number",
                                        "description": "Valor por pessoa. Sem valor, usa o preco_venda da categoria"
                                    },
                                    "valor_custo": {
                                        "type": "number",
                                        "description": "Custo por pessoa. Sem valor, usa o preco_custo da categoria"
                                    },
                                    "valor_extras": {
                                        "type": "number",
                                        "description": "Soma dos extras"
                                    },
                                    "extras": {
                                        "type": "array",
                                        "description": "Extras escolhidos"
                                    },
                                    "desconto": {
                                        "type": "number",
                                        "description": "Desconto aplicado"
                                    },
                                    "desconto_motivo": {
                                        "type": "string",
                                        "description": "Motivo do desconto"
                                    },
                                    "acrescimo": {
                                        "type": "number",
                                        "description": "Acréscimo aplicado"
                                    },
                                    "acrescimo_motivo": {
                                        "type": "string",
                                        "description": "Motivo do acréscimo"
                                    },
                                    "status": {
                                        "type": "string",
                                        "description": "reservado (default), confirmado, usado ou cancelado"
                                    },
                                    "origem": {
                                        "type": "string",
                                        "description": "Canal da venda. Default: api"
                                    },
                                    "campos_customizados": {
                                        "type": "object",
                                        "description": "Campos livres do integrador"
                                    }
                                },
                                "required": [
                                    "passeio_id",
                                    "categoria_id",
                                    "beneficiario_nome",
                                    "quantidade"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/vendas/{id}": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Detalhar venda",
                "description": "Retorna a venda com os itens do voucher, os pagamentos e os check-ins.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 508,
                                        "uuid": "3f1c0a2e-8b4d-4f6a-9c11-2d7e5a9b0c33",
                                        "passeio_id": 12,
                                        "categoria_id": 30,
                                        "cliente_id": 91,
                                        "beneficiario_nome": "Marina Torres",
                                        "beneficiario_documento": "123.456.789-00",
                                        "quantidade": 2,
                                        "valor_unitario": 120,
                                        "valor_extras": 30,
                                        "desconto": 0,
                                        "valor_total": 270,
                                        "status": "confirmado",
                                        "codigo_voucher": "K7PJ4RQ2",
                                        "checked_in": false,
                                        "origem": "api",
                                        "voucher_items_count": 2,
                                        "voucher_items": [
                                            {
                                                "id": 1044,
                                                "passeio_venda_id": 508,
                                                "categoria_nome": "Adulto",
                                                "numero_item": 1,
                                                "codigo_qrcode": "K7PJ4RQ2-01",
                                                "beneficiario_nome": "Marina Torres",
                                                "status": "valido",
                                                "usado_em": null
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Atualizar venda",
                "description": "Atualiza dados do beneficiário, extras e valores. Não muda status: use o endpoint próprio. Venda cancelada não pode ser editada (VENDA_CANCELADA).",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Venda atualizada com sucesso"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "beneficiario_nome": {
                                        "type": "string",
                                        "description": "Nome de quem vai fazer o passeio"
                                    },
                                    "beneficiario_documento": {
                                        "type": "string",
                                        "description": "CPF ou documento"
                                    },
                                    "beneficiario_telefone": {
                                        "type": "string",
                                        "description": "Telefone"
                                    },
                                    "sessao_id": {
                                        "type": "integer",
                                        "description": "Trocar a sessão (reagendamento)"
                                    },
                                    "extras": {
                                        "type": "array",
                                        "description": "Extras escolhidos"
                                    },
                                    "valor_extras": {
                                        "type": "number",
                                        "description": "Soma dos extras"
                                    },
                                    "desconto": {
                                        "type": "number",
                                        "description": "Desconto"
                                    },
                                    "desconto_motivo": {
                                        "type": "string",
                                        "description": "Motivo do desconto"
                                    },
                                    "acrescimo": {
                                        "type": "number",
                                        "description": "Acréscimo"
                                    },
                                    "acrescimo_motivo": {
                                        "type": "string",
                                        "description": "Motivo do acréscimo"
                                    },
                                    "campos_customizados": {
                                        "type": "object",
                                        "description": "Campos livres do integrador"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/passeios/vendas/{id}/status": {
            "patch": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Mudar status da venda",
                "description": "Não existe DELETE de venda: cancelar preserva voucher e financeiro. Ao cancelar, motivo_cancelamento é obrigatório e a data é carimbada.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Status atualizado"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "description": "reservado, confirmado, usado ou cancelado"
                                    },
                                    "motivo_cancelamento": {
                                        "type": "string",
                                        "description": "Obrigatório quando status=cancelado"
                                    }
                                },
                                "required": [
                                    "status"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/vendas/{id}/pagamentos": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar pagamentos da venda",
                "description": "Pagamentos lançados nesta venda.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 91,
                                            "passeio_venda_id": 508,
                                            "valor": 270,
                                            "forma": "pix",
                                            "data_pagamento": "2026-08-05"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Registrar pagamento",
                "description": "Lança um pagamento na venda.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Pagamento registrado"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "valor": {
                                        "type": "number",
                                        "description": "Valor pago"
                                    },
                                    "forma": {
                                        "type": "string",
                                        "description": "Forma de pagamento (pix, dinheiro, cartao...)"
                                    },
                                    "data_pagamento": {
                                        "type": "string",
                                        "description": "Data do pagamento. Default: agora"
                                    },
                                    "observacao": {
                                        "type": "string",
                                        "description": "Observação"
                                    }
                                },
                                "required": [
                                    "valor",
                                    "forma"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/passeios/vendas/{id}/voucher": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Voucher da venda",
                "description": "O voucher tem UM item por pessoa, cada um com seu QR code. Uma venda de 4 pessoas gera 4 itens, e o check-in pode ser individual.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "venda_id": 508,
                                        "codigo_voucher": "K7PJ4RQ2",
                                        "quantidade": 2,
                                        "itens": [
                                            {
                                                "id": 1044,
                                                "passeio_venda_id": 508,
                                                "categoria_nome": "Adulto",
                                                "numero_item": 1,
                                                "codigo_qrcode": "K7PJ4RQ2-01",
                                                "beneficiario_nome": "Marina Torres",
                                                "status": "valido",
                                                "usado_em": null
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/voucher/{codigo}": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Validar voucher por código",
                "description": "Usado na portaria. Procura primeiro pelo código do ITEM (o que está no QR de cada pessoa) e, se não achar, pelo código da venda. Busca case-insensitive, porque leitor de QR devolve em caixa variada. O campo \"tipo\" na resposta diz qual dos dois foi encontrado.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "codigo",
                        "in": "path",
                        "required": true,
                        "description": "Código do item do voucher ou da venda",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "tipo": "item",
                                        "item": {
                                            "id": 1044,
                                            "passeio_venda_id": 508,
                                            "categoria_nome": "Adulto",
                                            "numero_item": 1,
                                            "codigo_qrcode": "K7PJ4RQ2-01",
                                            "beneficiario_nome": "Marina Torres",
                                            "status": "valido",
                                            "usado_em": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/passeios/vendas/{id}/checkin": {
            "post": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Registrar check-in",
                "description": "Sem voucher_item_id, marca a venda inteira. Com ele, marca só aquela pessoa, que é o caso de grupo chegando em horários diferentes. A venda só passa para \"usado\" quando não resta item pendente. Recusa item já usado (ITEM_JA_USADO), item de outra venda (ITEM_DE_OUTRA_VENDA) e venda cancelada (VENDA_CANCELADA).",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Check-in registrado"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "voucher_item_id": {
                                        "type": "integer",
                                        "description": "Item do voucher, para check-in individual"
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude de onde o check-in foi feito"
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude"
                                    },
                                    "guia_id": {
                                        "type": "integer",
                                        "description": "Guia que registrou"
                                    },
                                    "registrado_por_nome": {
                                        "type": "string",
                                        "description": "Nome de quem registrou"
                                    },
                                    "metodo": {
                                        "type": "string",
                                        "description": "Método (qrcode, manual, api)"
                                    },
                                    "dispositivo": {
                                        "type": "string",
                                        "description": "Identificação do aparelho"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            }
        },
        "/passeios/vendas/{id}/checkins": {
            "get": {
                "tags": [
                    "Experiências"
                ],
                "summary": "Listar check-ins da venda",
                "description": "Histórico de check-ins, do mais recente para o mais antigo.",
                "security": [
                    {
                        "bearerAuth": [
                            "passeios:read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID da venda",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 22,
                                            "venda_id": 508,
                                            "data_hora": "2026-08-06T05:32:00-03:00",
                                            "metodo": "qrcode"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/webhooks/events": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Listar eventos disponíveis",
                "description": "Retorna todos os eventos que podem ser inscritos, agrupados por categoria (reservas, pagamentos, clientes, excursoes, contratos, checkin).",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "groups": {
                                            "reservas": {
                                                "label": "Reservas",
                                                "events": {
                                                    "reserva.criada": "Nova reserva criada",
                                                    "reserva.confirmada": "Reserva confirmada (pagamento OK)",
                                                    "reserva.cancelada": "Reserva cancelada",
                                                    "reserva.expirada": "Reserva expirada por falta de pagamento",
                                                    "vaga_pendente.preenchida": "Vaga pendente preenchida (convidado/comprador completou dados)"
                                                }
                                            },
                                            "pagamentos": {
                                                "label": "Pagamentos",
                                                "events": {
                                                    "pagamento.criado": "Novo pagamento registrado",
                                                    "pagamento.confirmado": "Pagamento confirmado",
                                                    "pagamento.estornado": "Pagamento estornado"
                                                }
                                            },
                                            "contratos": {
                                                "label": "Contratos",
                                                "events": {
                                                    "contrato.assinado": "Contrato assinado pelo cliente"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/webhooks": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Listar webhooks",
                "description": "Lista paginada de webhooks cadastrados.",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Página",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Itens (max 100)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 1,
                                            "name": "Integração Kommo CRM",
                                            "url": "https://meusistema.com.br/webhooks/viagilize",
                                            "events": [
                                                "reserva.criada",
                                                "reserva.confirmada",
                                                "pagamento.confirmado"
                                            ],
                                            "is_active": true,
                                            "last_triggered_at": "2026-04-25T17:30:11-03:00",
                                            "last_status": "success",
                                            "failure_count": 0,
                                            "created_at": "2026-04-20T10:00:00-03:00"
                                        }
                                    ],
                                    "meta": {
                                        "current_page": 1,
                                        "per_page": 20,
                                        "total": 1
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Criar webhook",
                "description": "Cadastra um webhook. Retorna o secret UMA UNICA VEZ — guarde com seguranca para validar HMAC nas entregas.",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Webhook criado. Guarde o secret — ele nao sera exibido novamente.",
                                    "data": {
                                        "webhook": {
                                            "id": 1,
                                            "name": "Integração Kommo CRM",
                                            "url": "https://meusistema.com.br/webhooks/viagilize",
                                            "events": [
                                                "reserva.criada",
                                                "reserva.confirmada",
                                                "pagamento.confirmado"
                                            ],
                                            "is_active": true,
                                            "last_triggered_at": "2026-04-25T17:30:11-03:00",
                                            "last_status": "success",
                                            "failure_count": 0,
                                            "created_at": "2026-04-20T10:00:00-03:00"
                                        },
                                        "secret": "whsec_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "description": "Nome para identificar o webhook"
                                    },
                                    "url": {
                                        "type": "string",
                                        "description": "URL HTTPS que recebera os eventos"
                                    },
                                    "events": {
                                        "type": "array",
                                        "description": "Lista de eventos para inscrever (ex: [\"reserva.criada\", \"pagamento.confirmado\"])"
                                    }
                                },
                                "required": [
                                    "name",
                                    "url",
                                    "events"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/webhooks/{id}": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Detalhes de um webhook",
                "description": "Retorna dados de um webhook (sem expor o secret).",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do webhook",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 1,
                                        "name": "Integração Kommo CRM",
                                        "url": "https://meusistema.com.br/webhooks/viagilize",
                                        "events": [
                                            "reserva.criada",
                                            "reserva.confirmada",
                                            "pagamento.confirmado"
                                        ],
                                        "is_active": true,
                                        "last_triggered_at": "2026-04-25T17:30:11-03:00",
                                        "last_status": "success",
                                        "failure_count": 0,
                                        "created_at": "2026-04-20T10:00:00-03:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            },
            "put": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Atualizar webhook",
                "description": "Atualiza nome, url, lista de eventos ou flag is_active.",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do webhook",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Webhook atualizado.",
                                    "data": {
                                        "id": 1,
                                        "name": "Integração Kommo CRM",
                                        "url": "https://meusistema.com.br/webhooks/viagilize",
                                        "events": [
                                            "reserva.criada",
                                            "reserva.confirmada",
                                            "pagamento.confirmado"
                                        ],
                                        "is_active": true,
                                        "last_triggered_at": "2026-04-25T17:30:11-03:00",
                                        "last_status": "success",
                                        "failure_count": 0,
                                        "created_at": "2026-04-20T10:00:00-03:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "description": "Novo nome"
                                    },
                                    "url": {
                                        "type": "string",
                                        "description": "Nova URL"
                                    },
                                    "events": {
                                        "type": "array",
                                        "description": "Nova lista de eventos"
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "description": "Ativa/desativa o webhook"
                                    }
                                },
                                "required": []
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Remover webhook",
                "description": "Remove definitivamente o webhook. Entregas em fila para esse webhook deixam de ser processadas.",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do webhook",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Webhook removido."
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/webhooks/{id}/regenerate-secret": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Regenerar secret",
                "description": "Gera um novo secret para o webhook. Invalida HMAC de qualquer entrega futura usando o secret antigo. Atualize seu receiver imediatamente.",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do webhook",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "message": "Secret regenerado.",
                                    "data": {
                                        "secret": "whsec_novoSecretGerado12345abcdef67890"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        },
        "/webhooks/{id}/test": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Testar webhook",
                "description": "Envia um evento test.ping para a URL configurada. Útil para validar que o receiver está respondendo corretamente.",
                "security": [
                    {
                        "bearerAuth": [
                            "webhooks:manage"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "ID do webhook",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sucesso",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "success": true,
                                        "status": "success",
                                        "response_code": 200,
                                        "response_time_ms": 245,
                                        "error_message": null
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Token inválido ou expirado"
                    },
                    "403": {
                        "description": "Escopo insuficiente"
                    },
                    "422": {
                        "description": "Erro de validação"
                    }
                }
            }
        }
    },
    "tags": [
        {
            "name": "Excursões",
            "description": "Gerenciamento de excursões e pacotes de viagem"
        },
        {
            "name": "Conteúdo (Excursão)",
            "description": "Página de conteúdo público da excursão (atrações, inclusos, regras, etc) que renderiza a vitrine. 1:1 com excursão."
        },
        {
            "name": "Fotos & Capa (Excursão)",
            "description": "Galeria pública da excursão (até 10 fotos) + capa. Upload via multipart/form-data ou URL externa com validações de segurança (mime real via finfo, magic bytes, anti-SSRF, dimensões máx, sem SVG)."
        },
        {
            "name": "Categorias (Excursão)",
            "description": "Sub-recurso de excursão: categorias de passageiro (Adulto, Criança, etc)"
        },
        {
            "name": "Embarques (Excursão)",
            "description": "Sub-recurso de excursão: pontos de embarque/retorno"
        },
        {
            "name": "Preços (Excursão)",
            "description": "Sub-recurso de excursão: valores por categoria × embarque"
        },
        {
            "name": "Variações",
            "description": "Opções de preço de um pacote de viagem (Leito, Semi-leito, tipo de quarto). Cada item de \"precos\" da excursão traz excursao_variacao_id; é aqui que se descobre o nome por trás desse id. Só existem em excursões com tipo_excursao=pacote_viagem."
        },
        {
            "name": "Pacote de Viagem",
            "description": "Sub-recursos da aba \"Editar Viagem > Pacote\": dados gerais, roteiro dia-a-dia, componentes, voos, cruzeiro, allotment, cotações com opções e vouchers. Exige excursão com `tipo_excursao=pacote_viagem` (exceto cotações, que aceitam qualquer tipo). Para gestão de quartos/rooming, use o módulo de Hospedagem (addon)."
        },
        {
            "name": "Custeio da Viagem",
            "description": "Custos operacionais da excursão (ônibus, guia, hospedagem, pedágio, alimentação, ingressos), precificação com composição de valores (overhead, lucro, comissão, taxas), cenários por ocupação, ponto de equilíbrio e rentabilidade real. Espelha a aba **Custeio** da edição da viagem. Requer addon `gestao-financeira` (custos vivem em `fin_contas_pagar`)."
        },
        {
            "name": "Passageiros",
            "description": "Gerenciamento de passageiros individuais das excursões"
        },
        {
            "name": "Clientes",
            "description": "Cadastro de clientes, dependentes e histórico de reservas"
        },
        {
            "name": "Reservas",
            "description": "Orders de reservas com geração de link de pagamento"
        },
        {
            "name": "Lista de Espera",
            "description": "Fila de espera por excursão. Quando uma vaga abre, o sistema notifica o primeiro da fila com janela de oferta limitada."
        },
        {
            "name": "Financeiro",
            "description": "Pagamentos e dados financeiros dos passageiros"
        },
        {
            "name": "Cupons",
            "description": "Cupons de desconto: CRUD, validação e aplicação em reservas."
        },
        {
            "name": "Guias",
            "description": "Cadastro de guias e designação em excursões"
        },
        {
            "name": "Veículos",
            "description": "Cadastro de veículos (ônibus, vans, carros)"
        },
        {
            "name": "Transportes",
            "description": "Cadastro de empresas de transporte e atribuição em excursões"
        },
        {
            "name": "Hospedagem",
            "description": "Addon Hospedagem — cadastro de hotéis/pousadas, tipos de quarto, suplementos, vínculo com excursões (allotment + valores) e alocação real de quartos para passageiros e guias. Requer addon `hospedagem` ativo no tenant (403 caso contrário)."
        },
        {
            "name": "Ingressos",
            "description": "Addon Ingressos — cadastro de atrações/eventos, categorias (tipos de ingresso com preço custo/venda), controle de estoque por data e vendas. Requer addon `ingressos` ativo no tenant (403 caso contrário)."
        },
        {
            "name": "Experiências",
            "description": "Módulo de Experiências Turísticas (passeios): catálogo com categorias, horários, extras, temporadas e fotos, além das vendas com voucher por pessoa e check-in individual. Requer o addon passeios-experiencias ativo no tenant."
        },
        {
            "name": "Webhooks",
            "description": "Cadastro e gestão de webhooks. Eventos chegam via POST com envelope padronizado (event, event_id UUID, created_at ISO 8601, data) + assinatura HMAC-SHA256 no header X-Viagilize-Signature."
        }
    ]
}