Cada produto traz `prerequisiteGroupIds`: os grupos de assinatura (planos) que ele exige quando é um adicional; vazio quando não exige nenhum. Traz também `commitmentMonths`: a duração do contrato em meses, ou `null` quando a assinatura não tem contrato. Traz `grantedCredits` e `grantedCreditsValidityDays` (créditos concedidos na compra). Traz `pricingMode` (`MONEY`, `POINTS` ou `POINTS_OR_MONEY`) e `pointsPrice` (o preço em pontos, `null` em `MONEY`), para todos os papéis. Produtos de sistema (`kind` `booking`, criado para recurso pago, e `download`) não entram na listagem; só `?kind=download` os lista, para a equipe.
**Quem vê o quê:** owner, admin, finance e SuperAdmin recebem a resposta completa (todos os status, `hasStock`, `stockQuantity`, `internalName`, `totalSales`, `activeSubscriptionsCount`). Qualquer outro papel recebe só o público: produtos `ACTIVE`, sem `hasStock`, `stockQuantity`, `internalName`, `totalSales`, `activeSubscriptionsCount`, `metadata` nem `requiresApproval`, e com `soldOut` (boolean) no lugar do estoque.
`totalSales` conta as compras concluídas; `activeSubscriptionsCount` conta as assinaturas em vigor do produto (status `ACTIVE`, `TRIALING`, `PAST_DUE` ou `PAUSED`): é o número de assinantes da coluna de Monetização › Assinaturas. Para produto avulso vem `0`. O filtro `status` é ignorado para quem não é da gestão.
**Busca e paginação:** `search` procura no servidor, em todas as páginas, pelo título e pelo slug (e, para a gestão, também pelo `internalName`), sem diferenciar maiúsculas nem acentos ("cota diamante" acha "Cota Diamante de Patrocínio"). Combina com `type`, `status` e `kind`. A resposta é paginada (`page`, `limit` até 50, padrão 20) e `pagination` traz `page`, `limit`, `total` e `totalPages` já com a busca e os filtros aplicados. Sem `search`, a resposta é a mesma de antes.