# API Ktalogu

## Visao geral

Esta documentacao descreve a camada versionada `/api/v1` da Ktalogu para consumo externo por integracoes, automacoes e futuros clientes como extensao Chrome e mobile.

Escopo desta fase:

- nao cria novos modulos de negocio
- nao altera banco
- nao altera telas
- nao mexe no modulo WhatsApp
- nao quebra rotas legadas existentes

Todas as respostas funcionais da `/api/v1` seguem o mesmo envelope:

```json
{
  "success": true,
  "data": {}
}
```

Erros seguem:

```json
{
  "success": false,
  "error": {
    "code": "missing_bearer_token",
    "message": "Token Bearer obrigatorio.",
    "details": null
  }
}
```

Observacao:

- `/api/v1/openapi` retorna o documento OpenAPI puro para compatibilidade com Swagger e geradores de cliente.
- `/api/v1/docs` entrega a interface Swagger UI baseada nesse documento.

## Endpoints de documentacao

- `GET /api/v1/health`
- `GET /api/v1/openapi`
- `GET /api/v1/docs`

## Como autenticar

### 1. Login

Use `POST /api/v1/auth/login` com email e senha.

Exemplo:

```http
POST /api/v1/auth/login
Content-Type: application/json

{
  "email": "owner@empresa.com",
  "password": "minha-senha-segura"
}
```

Resposta:

```json
{
  "success": true,
  "data": {
    "session": {
      "access_token": "eyJhbGciOi...",
      "refresh_token": "refresh-token-exemplo",
      "token_type": "bearer",
      "expires_at": 1763630112,
      "user": {
        "id": "8a33f8f4-6b8d-4ab3-9a90-2b4f5f34a999",
        "email": "owner@empresa.com"
      },
      "company": {
        "id": "11111111-1111-4111-8111-111111111111",
        "owner_id": "22222222-2222-4222-8222-222222222222",
        "tenant_ids": [
          "11111111-1111-4111-8111-111111111111",
          "22222222-2222-4222-8222-222222222222"
        ],
        "permissions": [
          "products.read",
          "categories.write",
          "quotes.write",
          "financial.read"
        ]
      }
    }
  }
}
```

### 2. Uso do token

Envie o access token em todas as rotas protegidas:

```http
Authorization: Bearer eyJhbGciOi...
```

### 3. Renovacao da sessao

Use `POST /api/v1/auth/refresh` com o `refresh_token`.

```http
POST /api/v1/auth/refresh
Content-Type: application/json

{
  "refresh_token": "refresh-token-exemplo"
}
```

### 4. Encerramento da sessao

Use `POST /api/v1/auth/logout` com:

- `Authorization: Bearer <access_token>`
- `refresh_token` no corpo

```http
POST /api/v1/auth/logout
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json

{
  "refresh_token": "refresh-token-exemplo"
}
```

## Regras de autenticacao e permissao

- o JWT e validado antes do acesso aos dados
- tokens expirados retornam `401 token_expired`
- requests sem bearer token retornam `401 missing_bearer_token`
- refresh token invalido retorna `401 invalid_refresh_token`
- o header `x-ktalogu-company-id` pode ser enviado para explicitar a empresa alvo
- se o header de empresa divergir da empresa resolvida pelo token, a API retorna `403 cross_company_access_denied`
- um usuario da empresa A nao pode consumir dados da empresa B
- as permissoes efetivas sao resolvidas pelo contexto da empresa autenticada

## Rate limiting

O rate limiting atual continua em memoria, mas agora esta documentado e padronizado por namespace de endpoint.

Headers devolvidos nas respostas protegidas:

- `X-RateLimit-Limit-IP`
- `X-RateLimit-Limit-User`
- `X-RateLimit-Remaining`
- `X-RateLimit-Reset`
- `Retry-After`

Comportamento ao exceder:

- status `429`
- `error.code = "rate_limited"`
- `error.details.limit` informa o limite aplicado
- `error.details.reset_at` informa o instante de reset da janela

Politicas aplicadas nesta etapa:

- `POST /api/v1/auth/login`: 10 req/min por IP
- `POST /api/v1/auth/refresh`: 20 req/min por IP
- `POST /api/v1/auth/logout`: 30 req/min por IP
- `GET /api/v1/auth/me`: 120 req/min por IP e por usuario
- `GET /api/v1/company`: 120 req/min por IP e por usuario
- `PUT /api/v1/company`: 60 req/min por IP e por usuario
- `GET /api/v1/products`: 120 req/min por IP e por usuario
- `GET /api/v1/products/{id}`: 120 req/min por IP e por usuario
- `GET /api/v1/categories`: 120 req/min por IP e por usuario
- `POST /api/v1/categories`: 60 req/min por IP e por usuario
- `GET /api/v1/categories/{id}`: 120 req/min por IP e por usuario
- `PATCH /api/v1/categories/{id}`: 60 req/min por IP e por usuario
- `DELETE /api/v1/categories/{id}`: 30 req/min por IP e por usuario
- `GET /api/v1/quotes`: 120 req/min por IP e por usuario
- `POST /api/v1/quotes`: 60 req/min por IP e por usuario
- `POST /api/v1/quotes/{id}/approve`: 30 req/min por IP e por usuario
- `GET /api/v1/payment-links`: 120 req/min por IP e por usuario
- `POST /api/v1/payment-links`: 60 req/min por IP e por usuario
- `GET /api/v1/payment-links/{id}`: 120 req/min por IP e por usuario
- `PATCH /api/v1/payment-links/{id}`: 60 req/min por IP e por usuario
- `DELETE /api/v1/payment-links/{id}`: 30 req/min por IP e por usuario

## Endpoints disponiveis

### Auth

- `POST /api/v1/auth/login`
- `POST /api/v1/auth/refresh`
- `POST /api/v1/auth/logout`
- `GET /api/v1/auth/me`

### Company

- `GET /api/v1/company`
- `PUT /api/v1/company`

### Products

- `GET /api/v1/products`
- `GET /api/v1/products/{id}`

Filtros:

- `q`
- `category`
- `status=all|active|inactive`
- `page`
- `per_page`

### Categories

- `GET /api/v1/categories`
- `POST /api/v1/categories`
- `GET /api/v1/categories/{id}`
- `PATCH /api/v1/categories/{id}`
- `DELETE /api/v1/categories/{id}`

### Quotes

- `GET /api/v1/quotes`
- `POST /api/v1/quotes`
- `POST /api/v1/quotes/{id}/approve`

### Payment Links

- `GET /api/v1/payment-links`
- `POST /api/v1/payment-links`
- `GET /api/v1/payment-links/{id}`
- `PATCH /api/v1/payment-links/{id}`
- `DELETE /api/v1/payment-links/{id}`

## Exemplos de consumo

### Consultar empresa autenticada

```bash
curl -X GET "http://localhost:3002/api/v1/company" \
  -H "Authorization: Bearer eyJhbGciOi..."
```

### Listar produtos com filtros

```bash
curl -X GET "http://localhost:3002/api/v1/products?q=caneca&status=active&page=1&per_page=20" \
  -H "Authorization: Bearer eyJhbGciOi..."
```

### Criar categoria

```bash
curl -X POST "http://localhost:3002/api/v1/categories" \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Canecas Personalizadas",
    "is_visible": true
  }'
```

### Criar orcamento

```bash
curl -X POST "http://localhost:3002/api/v1/quotes" \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "99999999-9999-4999-8999-999999999999",
    "seller_mode": "single",
    "primary_seller_user_id": "88888888-8888-4888-8888-888888888888",
    "items": [
      {
        "product_id": "55555555-5555-4555-8555-555555555555",
        "title": "Caneca Branca 325ml",
        "quantity": 10,
        "unit_price": 14.99
      }
    ]
  }'
```

### Criar link de pagamento

```bash
curl -X POST "http://localhost:3002/api/v1/payment-links" \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Caneca Premium",
    "amount": 199.90,
    "status": "active",
    "type": "one_time"
  }'
```

## Validacoes de entrada

Nesta etapa, a camada `/api/v1` passa a validar de forma explicita:

- `body` JSON deve ser objeto quando exigido
- `params` de IDs devem ser UUID validos
- `query` numericas usam inteiros positivos
- enums de consulta, como `status`, aceitam apenas valores documentados
- erros retornam mensagens amigaveis no envelope padrao

## Documentacao interativa

- Swagger UI: `GET /api/v1/docs`
- OpenAPI bruto: `GET /api/v1/openapi`

## Recomendacao de consumo

- autentique uma vez e armazene `access_token` e `refresh_token`
- renove a sessao antes do vencimento quando necessario
- envie `x-ktalogu-company-id` apenas se precisar reforcar explicitamente o escopo da empresa
- trate `401`, `403` e `429` como respostas esperadas de integracao
- use o contrato OpenAPI como fonte primaria para gerar clientes e validadores
