Skip to content

Gerenciamento de Lista de Desejos

Guia de implementação de lista de desejos com prioridade e notas. Explica o padrão de ocultação de existência, adição idempotente e múltiplos parâmetros de caminho.

Visão Geral

  • Usuários criam listas de desejos com nome (pública/privada)
  • Cada lista de desejos recebe produtos (com priority: high/medium/low e note opcional)
  • Listas de desejos privadas retornam 404 para não-donos (padrão de ocultação de existência)
  • Adição de produto é idempotente (200 se já existe, 201 se novo)
  • Sem ordenação (sem gerenciamento de posição) — principal diferença do Content Collection (FT149)

Endpoints

MétodoCaminhoDescrição
POST/wishlistsCriar lista de desejos
GET/wishlists/{id}Obter lista de desejos (pública ou própria)
PUT/wishlists/{id}Alterar nome e configuração de privacidade
DELETE/wishlists/{id}Deletar lista de desejos
POST/wishlists/{id}/itemsAdicionar produto (idempotente)
DELETE/wishlists/{id}/items/{productId}Remover produto

Design do Banco de Dados

sql
CREATE TABLE wishlists (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER NOT NULL,
    name TEXT NOT NULL,
    is_public INTEGER NOT NULL DEFAULT 0,
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

CREATE TABLE wishlist_items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    wishlist_id INTEGER NOT NULL,
    product_id INTEGER NOT NULL,
    priority TEXT NOT NULL DEFAULT 'medium',
    note TEXT,
    added_at TEXT NOT NULL,
    UNIQUE (wishlist_id, product_id),
    CHECK (priority IN ('high', 'medium', 'low')),
    FOREIGN KEY (wishlist_id) REFERENCES wishlists(id),
    FOREIGN KEY (product_id) REFERENCES products(id)
);

Ao contrário do Content Collection (FT149), não há coluna position. UNIQUE (wishlist_id, product_id) é a defesa no nível do banco para adição idempotente.

Padrão de Ocultação de Existência

php
$isOwner = $actorId !== null && (int) $wishlist['user_id'] === $actorId;
$isPublic = (bool) $wishlist['is_public'];

if (!$isOwner && !$isPublic) {
    return $this->responseFactory->create(['error' => 'wishlist not found'], 404);
}

Apenas GET retorna 404. PUT/DELETE/POST items retornam 403 para informar ao dono que não tem permissão.

Adição Idempotente de Item

php
$existing = $this->repository->findItem($id, $productId);
if ($existing !== null) {
    return $this->responseFactory->create([
        'message' => 'already in wishlist',
        'product_id' => $productId,
        'priority' => $existing['priority'],
        'note' => $existing['note'],
    ], 200);
}
$now = date('c');
$this->repository->addItem($id, $productId, $priority, $note, $now);
return $this->responseFactory->create([...], 201);

Validação de priority (valores inválidos fazem fallback para padrão)

php
private const array VALID_PRIORITIES = ['high', 'medium', 'low'];

$priority = isset($body['priority']) && is_string($body['priority'])
    && in_array($body['priority'], self::VALID_PRIORITIES, true)
    ? $body['priority']
    : 'medium';

Valores de priority inválidos fazem fallback para 'medium' em vez de erro. Isso lida com segurança com valores de priority desconhecidos que o cliente pode enviar para compatibilidade futura.

Exemplo de Resposta GET /wishlists/

json
{
  "id": 1,
  "user_id": 1,
  "name": "Lista de Aniversário",
  "is_public": true,
  "item_count": 2,
  "items": [
    {
      "product_id": 3,
      "product_name": "Fone de Ouvido Sem Fio",
      "priority": "high",
      "note": "Prefiro cor preta",
      "added_at": "2026-05-21T..."
    },
    {
      "product_id": 1,
      "product_name": "Caneca de Café",
      "priority": "low",
      "note": null,
      "added_at": "2026-05-21T..."
    }
  ],
  "created_at": "2026-05-21T...",
  "updated_at": "2026-05-21T..."
}

Diferenças entre Collection e Lista de Desejos

AspectoCollection (FT149)Lista de Desejos (FT151)
OrdenaçãoCom gerenciamento de posiçãoSem (ordem de adição)
Metadados do itemNenhumpriority + note
Limite50 itensSem limite
Caso de usoLista de leitura, curadoriaLista de desejos, registro de presentes

Padrão de Verificação de Propriedade

php
if ((int) $wishlist['user_id'] !== $actorId) {
    return $this->responseFactory->create(['error' => 'access denied'], 403);
}

O mesmo padrão é usado em todos os endpoints PUT/DELETE/POST items.

Publicado sob a licença MIT.