meta {
  name: 4. Atualizar Campanha
  type: http
  seq: 4
}

patch {
  url: {{baseUrl}}/api/campaigns/{{campaignId}}
  body: json
  auth: none
}

body:json {
  {
    "title": "Newsletter de Agosto (revisada)",
    "contactListId": "{{contactListId}}"
  }
}

docs {
  Requer sessão + ser dona da campanha (404 unificado, igual ao GET).

  ⚠️ **Esta rota não valida o body com Zod nem com nada** — aceita qualquer JSON. Só 4 chaves são de fato lidas e aplicadas: `title`, `subject`, `senderId`, `contactListId`. **`htmlBody` NÃO PODE ser editado por aqui** — se você enviar `htmlBody` no corpo, ele é silenciosamente ignorado (confirmado no repositório: `update()` nunca lê essa chave).

  Detalhes de comportamento: valores "falsy" (`""`) em `title`/`subject`/`senderId` são ignorados (não atualiza, não dá erro — não é possível "limpar" esses campos assim). `contactListId: null` explícito REMOVE a lista associada; omitir o campo mantém o valor atual. Se `senderId`/`contactListId` apontar para um id que não existe, a violação de FK do Postgres não é tratada como `AppError` → **500**, não 400.

  Sucesso: 200, `Campaign` bruto pós-update (mesmos campos escalares do create, sem relations).
}
