API Reference¶
Documentação oficial dos endpoints expostos (NestJS). Tudo aqui reflete exatamente os controllers fornecidos.
Autorização:
- JWT obrigatório para
restaurants/*euser-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 restauranteGET /restaurants— Listar meus restaurantes (com filtros)GET /restaurants/:id— Detalhar restauranteGET /restaurants/slug/:slug— Buscar porslugPATCH /restaurants/:id— Atualizar restauranteDELETE /restaurants/:id— Excluir restauranteGET /restaurants/:id/statistics— Estatísticas do restaurante
Usuário × Restaurante (@ApiTags('user-restaurant'))¶
GET /users/me/restaurants— Listar meus restaurantesGET /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 vincularPOST /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:
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
transactionKey→ 400 - Teste (
STORE1001/isTestTransaction):transactionKeysufixado 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:
JwtAuthGuardem todos; alguns exigem tambémRolesGuard+@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).