Pular para conteúdo

API Reference

Documentação oficial dos endpoints expostos (NestJS). Tudo aqui reflete exatamente os controllers fornecidos.

Autorização:

  • JWT obrigatório para restaurants/* e user-restaurant/* (guard: JwtAuthGuard).
  • Webhook Nayax usa NayaxAuthGuard (assinatura/principal técnica do integrador).

Sumário de Endpoints

Webhooks

  • POST /webhooks/nayax — Recebe eventos Nayax (ingest + outbox)

Restaurantes (@ApiTags('restaurants'))

  • POST /restaurants — Criar restaurante
  • GET /restaurants — Listar meus restaurantes (com filtros)
  • GET /restaurants/:id — Detalhar restaurante
  • GET /restaurants/slug/:slug — Buscar por slug
  • PATCH /restaurants/:id — Atualizar restaurante
  • DELETE /restaurants/:id — Excluir restaurante
  • GET /restaurants/:id/statistics — Estatísticas do restaurante

Usuário × Restaurante (@ApiTags('user-restaurant'))

  • GET /users/me/restaurants — Listar meus restaurantes
  • GET /restaurants/:restaurantId/users — Listar usuários do restaurante (OWNER/ADMIN/MANAGER)
  • GET /restaurants/:restaurantId/user/:userId — Detalhar vínculo de um usuário (OWNER/ADMIN/MANAGER)
  • POST /restaurants/:restaurantId/users/create-and-link — Criar usuário e vincular
  • POST /restaurants/:restaurantId/users — Adicionar usuário ao restaurante (OWNER/ADMIN)
  • PATCH /restaurants/:restaurantId/users/:userId/role — Atualizar role (OWNER)
  • DELETE /restaurants/:restaurantId/users/:userId — Remover usuário (OWNER/ADMIN)
  • GET /restaurants/:restaurantId/users/stats — Contagem por role (OWNER/ADMIN)
  • POST /restaurants/:restaurantId/transfer-ownership — Transferir propriedade (OWNER)
  • GET /restaurants/:restaurantId/my-role — Ver minha role + permissões

Autenticação

JWT (padrão)

Todos os endpoints acima exceto o webhook exigem JWT:

Authorization: Bearer <seu_token_jwt>

Exemplo para obter token (ilustrativo):

curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"admin123"}'

NayaxAuthGuard (webhook)

POST /webhooks/nayax valida a requisição via NayaxAuthGuard e injeta req.user para o serviço.


Webhooks

POST /webhooks/nayax

Ingestão de eventos Nayax + criação de outboxJob (CREATE/CANCEL).

Guards: NayaxAuthGuard (requer principal válido) Respostas:

  • 200 OK — Evento recebido e processado (ou duplicata de teste ignorada)
  • 400 Bad Request — Sem autenticação no contexto do serviço, ausência de vínculo OWNER, ou transação duplicada em produção

Notas de negócio:

  • Produção: duplicidade por transactionKey400
  • Teste (STORE1001/isTestTransaction): transactionKey sufixado por timestamp e duplicatas são ignoradas (idempotência relaxada)

Restaurantes

Guard: JwtAuthGuard (todos).

POST /restaurants

Cria restaurante e o vincula ao usuário autenticado.

Body: CreateRestaurantDto Respostas: 201 Created (payload em { message, data }) | 400 inválido

GET /restaurants

Lista seus restaurantes, com filtros de QueryRestaurantDto.

Query: QueryRestaurantDto Resposta: 200 lista paginada/filtrada (shape definido pelo service)

GET /restaurants/:id

Detalhes do restaurante (verifica acesso do usuário).

Resposta: 200 | 404 não encontrado | 403 sem acesso

GET /restaurants/slug/:slug

Busca por slug.

Resposta: 200 | 404

PATCH /restaurants/:id

Atualiza dados do restaurante (autorização interna no service).

Body: UpdateRestaurantDto Resposta: 200 { message, data } | 403 | 404

DELETE /restaurants/:id

Exclui restaurante (apenas proprietário).

Resposta: 200 | 403 | 404

GET /restaurants/:id/statistics

Retorna estatísticas agregadas do restaurante.

Resposta: 200 (shape definido pelo service)


Usuário × Restaurante

Guard: JwtAuthGuard em todos; alguns exigem também RolesGuard + @Roles(...).

GET /users/me/restaurants

Retorna os restaurantes onde o usuário atual possui vínculo.

Resposta: 200 { restaurants }


GET /restaurants/:restaurantId/users

Lista usuários do restaurante.

Guards: RolesGuard + @Roles(OWNER, ADMIN, MANAGER) Regra extra: canManage(currentUser, restaurantId) deve ser true Resposta: 200 { users } | 403 sem permissão

GET /restaurants/:restaurantId/user/:userId

Detalhe do vínculo de um usuário específico.

Guards: RolesGuard + @Roles(OWNER, ADMIN, MANAGER) Regra extra: canManage Resposta: 200 { user } | 403


POST /restaurants/:restaurantId/users/create-and-link

Cria um usuário e já vincula ao restaurante.

Body: CreateUserAndLinkDto Resposta: 201/200 conforme service

POST /restaurants/:restaurantId/users

Adiciona usuário existente ao restaurante.

Guards: RolesGuard + @Roles(OWNER, ADMIN) Regra extra: hasPermission(currentUser, restaurantId, [OWNER, ADMIN]) Body: AddUserToRestaurantDto (userId, role) Resposta: 201 { message, data } | 400 já vinculado | 403


PATCH /restaurants/:restaurantId/users/:userId/role

Altera a role de um usuário no restaurante.

Guards: RolesGuard + @Roles(OWNER) Regra extra: isOwner(currentUser, restaurantId) Body: UpdateUserRoleDto (role) Resposta: 200 { message, data } | 403


DELETE /restaurants/:restaurantId/users/:userId

Remove usuário do restaurante.

Guards: RolesGuard + @Roles(OWNER, ADMIN) Regra extra: hasPermission(currentUser, restaurantId, [OWNER, ADMIN]) Resposta: 200 { message } | 403


GET /restaurants/:restaurantId/users/stats

Retorna contagem de usuários por role.

Guards: RolesGuard + @Roles(OWNER, ADMIN) Resposta:

{
  "restaurantId": "uuid",
  "countsByRole": { "OWNER": 1, "ADMIN": 2, "MANAGER": 3, "EMPLOYEE": 10, "VIEWER": 4 },
  "total": 20
}

POST /restaurants/:restaurantId/transfer-ownership

Transfere a propriedade do restaurante.

Guards: RolesGuard + @Roles(OWNER) Body: TransferOwnershipDto (newOwnerId) Resposta: 200 (resultado do service) | 403


GET /restaurants/:restaurantId/my-role

Retorna sua role atual no restaurante e as permissões derivadas.

Resposta (200):

{
  "userId": "uuid",
  "restaurantId": "uuid",
  "role": "ADMIN",
  "permissions": ["manage_users","manage_data","view_reports","manage_settings"]
}

Erro: 403/404 quando não vinculado (service lança erro)

Permissões por role (helper do controller):

  • OWNER: ["all"]
  • ADMIN: ["manage_users","manage_data","view_reports","manage_settings"]
  • MANAGER: ["manage_data","view_reports","manage_operations"]
  • EMPLOYEE: ["create_transactions","view_data"]
  • VIEWER: ["view_data"]

Erros & Códigos

Tabela rápida (detalhe em Glossário de Erros):

Código/Status Significado
400 Requisição inválida / regra não atendida
401 Não autenticado
403 Sem permissão/role
404 Recurso não encontrado
409 Conflito (ex.: Prisma P2002)
422 Semântica inválida
500 Erro interno
P2002 Unique constraint violation → HTTP 409
P2025 Registro alvo ausente → HTTP 404

Para a matriz completa e padrões de DLQ/FAILED nos jobs, ver: Glossário de Códigos de Erro.


Exemplos de cURL

Criar restaurante

curl -X POST http://localhost:3000/restaurants \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Loja Centro",
    "slug": "loja-centro",
    "address": "Rua X, 123"
  }'

Adicionar usuário ao restaurante (OWNER/ADMIN)

curl -X POST http://localhost:3000/restaurants/$RID/users \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "userId": "USER_ID", "role": "EMPLOYEE" }'

Webhook Nayax (com guard do integrador)

curl -X POST http://localhost:3000/webhooks/nayax \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $NAYAX_SIGNATURE_OR_TOKEN" \
  -d '{ "transactionKey": "abc", "storeCode": "STORE1001", "...": "..." }'

Rate Limiting

Sem rate limiting por padrão. Em produção, recomenda-se configurar (ex.: @nestjs/throttler) por rota, especialmente no webhook.


Changelog

  • v1.0.0 — Primeira versão alinhada aos controllers reais (RestaurantController, UserRestaurantController, NayaxController).