# API JSON (v1) vs API REST v2 — variáveis e mapeamento para `accommodation`

Este documento compara as **duas versões** da API Beds24 / GoCore Channel usadas no projeto e indica **que dados cada uma pode fornecer** para a tabela `gocore.accommodation` (e contexto de quartos). A coluna **`accommodation.api_map`** (JSON, migração 15) guarda, por propriedade, um resumo das **fontes usadas** no último import (`gocore_channel_import.php`).

**Persistência:** os dados de alojamento importados ou enriquecidos pelo canal devem ficar na base **`gocore`**, em tabelas cujo nome começa por **`accommodation_`** (principalmente `accommodation` e `accommodation_bedroom`, mais tabelas PMS/ofertas da migração 13/14). O objecto completo da API continua espelhado em **`beds24_extra`** / **`beds24_room_extra`**. Ligações a outros módulos (ex. `channel_property_connections`) usam o **`accommodation.id`** interno.

---

## 1. Resumo das duas APIs

| Aspeto | **API JSON (v1 / “legacy”)** | **API REST v2** |
|--------|------------------------------|-----------------|
| **Base URL** | `https://api.beds24.com/json` (POST por endpoint); `getPropertyContent` pode usar `https://www.beds24.com/api/json` | `https://api.beds24.com/v2` |
| **Autenticação** | Corpo JSON: `authentication.apiKey` | Header HTTP: `token: {token}` (invite / long-life; scope **properties** para `/properties`) |
| **Estilo** | Um **endpoint por operação** no path: `/json/getProperty`, `/json/getProperties`, … | **Recursos REST**: `GET /properties`, `GET /properties/rooms`, … |
| **Uso principal no import** | Lista (`getProperties`) + detalhe (`getProperty` com **propKey** longo) + conteúdo (`getDescriptions`, `getPropertyContent`) | Enriquecimento: linha da propriedade em `GET /properties` (paginado); quartos com `GET /properties/rooms` ou `GET /properties?includeAllRooms=true` |

O merge guardado em **`beds24_extra`** é tipicamente: `array_merge($listaItem, $getProperty, $v2Prop)` — ou seja, chaves das três fontes sobrescrevem na ordem (V2 por último no código actual).

---

## 2. API JSON v1 — endpoints relevantes e variáveis típicas

### 2.1 `getProperties` (lista)

- **Entrada:** `authentication` apenas (e filtros se existirem na conta).
- **Saída:** estrutura variável; frequentemente cada item tem `propertyData` ou campos no root: **propId**, **propKey**, **name**, **propertyType**, **tags**, morada parcial, etc.
- **No import:** cada elemento da lista é a base **`$inner`**; alimenta `api_id` / identificadores e entra no **`merged`**.

### 2.2 `getProperty` (detalhe por propriedade)

- **Entrada:** `authentication` + identificação da propriedade (**propKey** longo ≥ 16 caracteres nas contas típicas).
- **Saída:** objecto **plano** com dezenas a centenas de chaves (depende da conta e templates). O código mapeia explicitamente em `GocoreChannelApi::mapPropertyToForm()`:

| Campo lógico | Chaves típicas na resposta (primeira que existir) |
|--------------|---------------------------------------------------|
| Nome | `name` |
| Identificadores | `propKey`, `propId`, `id`, `propertyId`, `ref`, `propRef` |
| Morada | `address`, `city`, `state`, `country`, `postcode` |
| Coordenadas | `latitude`, `longitude` |
| Contacto | `contactFirstName`, `contactLastName`, `phone`, `mobile`, `fax`, `email`, `web` |
| Negócio | `currency`, `cutOffHour`, `vatRate` |
| Tipo / prioridade | `propTypeId`, `controlPriority` |
| Webhooks | `notifyUrl`, `notifyData`, `notifyHeader` |
| Quartos (aninhado) | `roomTypes` **ou** `rooms` **ou** `roomUnits` — por item: `roomId` / `room_id` / `id`, `name` / `roomType`, `qty`, `minPrice` |

Outras chaves **comuns** na mesma resposta (ficam em `beds24_extra` e podem alimentar extractors): **`template1`…`template8`**, prefixos **OTA** (`booking*`, `airbnb*`, `agoda*`, …), **`bookingRules`**, horários tipo **`checkInStart` / `checkInEnd` / `checkOut`**, etc. — ver `extractBeds24TemplatesJson`, `extractBeds24ChannelIntegrationsJson`, `extractBeds24UiParityForDb`.

### 2.3 `getPropertyContent` / `getDescriptions`

- Textos, imagens estruturadas, tags para **`description_short`**, **`description_long`**, **`pictures`**, **`tags`** (import separado por propriedade).
- Não substituem o objecto completo de `getProperty`; complementam conteúdo marketing.

### 2.4 Limitações típicas da v1

- Sem modelo único documentado no Swagger do projeto: nomes de chaves podem variar.
- Quartos: se a lista vier só de `getProperty` sem **roomId**, o mapeamento para `accommodation_bedroom.api_room_id` fica incompleto — daí o uso da **v2** para `/properties/rooms`.

---

## 3. API REST v2 — recursos usados no código e variáveis

Referência interna: `accommodation/docs/BEDS24_API_V2.md` e [Swagger](https://api.beds24.com/v2/).

### 3.1 `GET /properties` (paginado)

- **Query:** `page=`, opcional `includePictures=true`, etc.
- **Resposta:** `data[]` cada elemento é uma propriedade.
- **Campos frequentes** (Swagger / wiki; nomes em **camelCase**): `id` (integer, **Property id**), `name`, `propertyType`, `currency`, `address`, `city`, `state`, `country`, `postcode`, `latitude`, `longitude`, `checkInStart`, `checkInEnd`, `checkOut`, `account`, imagens em estruturas aninhadas, etc.
- **No import:** indexado por `id` string → **`$v2Prop`** fundido no `merged`; reforça `propertyType`, fotos via V2 quando configurado, etc.

### 3.2 `GET /properties/rooms` ou `GET /properties?includeAllRooms=true`

- **Parâmetros:** `propertyId[]`, `id[]` (room), `includeTexts`, `includeOffers`, `includePictures`, …
- **Cada quarto (exemplos):** `id`, `propertyId`, `name`, `roomType`, `qty`, `minPrice`, `maxPeople`, `maxAdult`, `maxChildren`, `minStay`, `maxStay`, `restrictionStrategy`, `taxPercentage`, `taxPerson`, …
- **No import:** `room.id` → `accommodation_bedroom.api_room_id`; `propertyId` → corresponde a `accommodation.api_id`.

### 3.3 Outros segmentos v2 (não gravados linha-a-linha em `accommodation` hoje)

- **Inventory:** `/inventory/rooms/calendar`, `/inventory/rooms/offers`, … — calendário, ofertas por critério.
- **Bookings:** `GET /bookings` — reservas, `apiSourceId`, etc.
- **Accounts:** `GET /accounts` — alinhável a contas reseller.

---

## 4. Mapeamento conceptual: colunas `accommodation` ← fontes

Legenda: **v1** = merge que inclui `getProperties` + `getProperty`; **v2** = objecto `GET /properties` para o mesmo `id`; **extra** = extractors sobre `merged`; **content** = getDescriptions / getPropertyContent.

| Coluna / área | Principalmente de | Notas |
|---------------|-------------------|--------|
| `id` | BD | Interno |
| `api_id` | v1 lista + v2 `id` | Property id numérico preferido |
| `beds24_prop_key` | v1 `propKey` | Chave longa |
| `name`, `location_*`, `contact_*`, `currency`, `cutOffHour`, `vatRate` | v1 `mapPropertyToForm` + v2 sobrescreve homólogos | Colunas espelho na BD |
| `type` / `propertyType` | v1 + v2 | Migração com coluna `type` |
| `description_*`, `pictures`, `tags` | **content** APIs + v1/v2 se vierem no merge | |
| `beds24_extra` | **merge completo** | Todas as chaves v1+v2 conhecidas no import |
| `beds24_templates` | v1 `template1..8` no merge | |
| `beds24_channel_integrations` | v1 chaves OTA no merge | |
| `beds24_*` (notify, sync, UI JSON 13/14) | extractors sobre **merged** | Podem vir de v1 ou v2 consoante chaves presentes |
| `beds24_permit_id`, `beds24_type_of_booking` | v1/v2 **merged** (migração 16) | Ecrã **Description**: registo turístico e tipo de reserva; ver `extractBeds24PropertyDescriptionScalars` |
| `api_map` | **import** | Metadados: que endpoints contribuíram; amostra de chaves do merge |

**Quartos** (`accommodation_bedroom`): nomes/qty de v1 **ou** v2; **api_room_id** fiável sobretudo com **v2** (`GET /properties/rooms`).

---

## 5. Estrutura sugerida para `api_map` (JSON)

Gerada em PHP (`GocoreChannelApi::buildAccommodationApiMapPayload`). Campos típicos:

| Chave | Significado |
|-------|-------------|
| `schema` | Versão do objecto (ex.: `1`) |
| `updated_at` | ISO 8601 (UTC) |
| `property_beds24_id` | `api_id` / Property id |
| `sources_used.json_v1.getProperty` | `true` se `getProperty` devolveu dados úteis |
| `sources_used.json_v1.getProperties_list` | `true` (sempre que há item de lista) |
| `sources_used.json_v1.getDescriptions` | `true` se conteúdo veio de getDescriptions |
| `sources_used.json_v1.getPropertyContent` | `true` se getPropertyContent contribuiu |
| `sources_used.rest_v2.get_properties` | `true` se havia linha V2 para este id |
| `sources_used.rest_v2.rooms_endpoint` | `true` se quartos desta propriedade vieram de `/properties/rooms` ou fallback `includeAllRooms` |
| `merged_top_level_key_count` | número de chaves no primeiro nível do merge |
| `merged_top_level_keys_sample` | até 120 nomes de chaves (auditoria; não substitui `beds24_extra`) |

Para um **mapa campo-a-campo** futuro (qual API ganha para cada coluna), pode acrescentar-se um objecto `column_winners` numa versão posterior do schema.

---

## 6. Leitura adicional

- `BEDS24_API_V2.md` — segmentos Swagger, `apiSourceId`, IDs Property/Room.
- `GocoreChannelApi.php` — implementação real dos pedidos e extractors.
- `api/gocore_channel_import.php` — ordem do merge e gravação na BD.
