# GroupOlx Connector

Conector oficial do **Grupo OLX** (VRSync) — Sprint 008.

Namespace: `ImovelZapAi\Publishing\Connectors\GroupOlx\`

## Missão

```text
NormalizedListing → Feed VRSync → Validar → URL pública → Grupo OLX importa
```

**Adaptador de formato** — não “integração com portal”. O módulo produz VRSync válido; a distribuição OLX/ZAP/Viva Real é da plataforma + conta da imobiliária.

Ver: [`docs/architecture/PublishingHub.md`](../../../../docs/architecture/PublishingHub.md)

## Estrutura

```text
Connectors/GroupOlx/
├── Domain/           # Identidade, enums de portal, exceções
├── Application/      # Ports + DTOs (sem Property, sem Controllers)
├── Infrastructure/   # Provider + adapters (etapas seguintes)
├── Presentation/     # Rotas HTTP do conector
└── Shared/           # Package metadata
```

## Ports

| Interface | Papel |
|-----------|-------|
| `GroupOlxListingMapperInterface` | Canônico → DTO VRSync (sem XML) |
| `VrsyncXmlBuilderInterface` | DTO → string XML UTF-8 (sem salvar) |
| `GroupOlxFeedValidatorInterface` | Valida feed/XML → lista de erros |
| `GroupOlxPublicFeedInterface` | Persiste/resolve URL pública pré-gerada |
| `GroupOlxFeedBuilderInterface` | Canônico → feed VRSync XML |
| `GroupOlxConnectorInterface` | Orquestra publishFeed / URL |
| `FeedStorageInterface` | Persiste XML versionado (Local / R2) |

## Dashboard

Painel no Centro de publicação (`/publicacao`):

- XML válido · última geração · quantidade de anúncios
- erros · URL pública · tamanho XML · tempo de geração

Query: `GetGroupOlxDashboardQuery` — lê storage + validator + logs (não gera XML).

## PublicationLogs

Tabela `group_olx_publication_logs` (append-only):

| Campo | Conteúdo |
|-------|----------|
| `generated_at` | Momento da geração |
| `duration_ms` | Tempo de geração |
| `listing_count` | Quantidade de imóveis |
| `errors` / `warnings` | Listas JSON |
| `triggered_by` | Usuário responsável |
| `tenant_id` | Tenant (FK `restrictOnDelete`) |

`delete()` lança `GroupOlxPublicationLogImmutableException`.

## Storage

```text
publishing/{tenant_id}/group-olx/
  current.xml
  meta.json
  versions/{version}_{hash8}.xml
```

Driver: `PUBLISHING_GROUP_OLX_STORAGE_DRIVER=local|r2`

## Fila

```text
PropertyChanged → GenerateVrsyncFeedJob → Mapper → Builder → Validator → Storage → Log
```

Nunca gera XML na request HTTP. Worker: `queue:work --queue=publishing`

## Feed público

```text
GET /feed/{tenant-slug}/vrsync.xml
```

- sem autenticação
- lê apenas XML em cache
- `ETag` / `Last-Modified` / `304`
- gzip se `Accept-Encoding: gzip`

## Regras

- Consome **apenas** `NormalizedListing`
- Nunca acessa `PropertyModel`
- Nenhuma regra do portal fora deste módulo
- Application não depende de Controllers

## Identidade

| Campo | Valor |
|-------|-------|
| Slug | `group_olx` |
| Nome | Grupo OLX |
| Formato | VRSync 1.0 |

## Documentação

- Sprint: [`docs/sprints/SPRINT_008_GROUP_OLX_CONNECTOR.md`](../../../../docs/sprints/SPRINT_008_GROUP_OLX_CONNECTOR.md)
- Parent: [`packages/Publishing/README.md`](../../../README.md)
