Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ Nao e necessario rodar o projeto localmente para validar o fluxo principal do de
- Upstash Redis como Redis gerenciado para armazenar a fila e o estado dos jobs.
- JSONPlaceholder como endpoint externo de simulacao da Meta API.

Documentacao interativa da API:

```text
https://api-fury.onrender.com/docs
```

OpenAPI JSON:

```text
https://api-fury.onrender.com/openapi.json
```

### Como testar o deploy

Crie um job:
Expand Down Expand Up @@ -58,6 +70,12 @@ Exemplo de retorno esperado apos o worker processar:

Tambem e possivel testar validacao enviando um payload invalido. A API retorna `400` com os erros detalhados do Zod.

### Documentacao com Scalar

Foi adicionado Scalar para expor uma documentacao interativa baseada em OpenAPI. A especificacao e gerada pelo `@nestjs/swagger`, a partir dos controllers e dos DTOs de documentacao, e renderizada pelo `@scalar/nestjs-api-reference` em `/docs`.

Essa decisao deixa a avaliacao mais direta: quem revisar o projeto consegue ver os endpoints, payloads, enums, respostas esperadas e erros sem precisar ler todo o codigo primeiro. Como o desafio nao pede front-end, a documentacao interativa entrega uma experiencia de exploracao leve sem adicionar uma interface desnecessaria ao produto.

### Decisao de deploy

Foram consideradas algumas opcoes para deploy gratuito ou de baixo custo:
Expand Down Expand Up @@ -87,6 +105,7 @@ O uso dessas ferramentas nao substituiu as decisoes tecnicas: a arquitetura, as
- Redis local via Docker para desenvolvimento e Upstash Redis com TLS para deploy.
- Testes unitarios cobrindo regra de idempotencia, validacao do webhook e cenarios de sucesso/falha/timeout da chamada externa.
- CI no GitHub Actions rodando typecheck, lint, testes e build a cada push/PR na `main`.
- Documentacao Scalar com contrato OpenAPI para facilitar avaliacao, teste manual e entendimento dos payloads.
- Cuidados de seguranca: `.env` fora do Git, `.env.example` documentado, `helmet`, logs sem payload completo e sem chaves sensiveis versionadas.

## Stack
Expand All @@ -96,6 +115,7 @@ O uso dessas ferramentas nao substituiu as decisoes tecnicas: a arquitetura, as
- NestJS
- Zod
- BullMQ
- Scalar API Reference
- Redis local via Docker Compose ou Upstash Redis no deploy
- Jest
- ESLint
Expand Down Expand Up @@ -150,6 +170,8 @@ Referencias oficiais consultadas:

- `POST /webhook/violation` recebe o webhook.
- `GET /` e `GET /health` retornam status operacional simples.
- `GET /docs` exibe a documentacao interativa Scalar.
- `GET /openapi.json` expoe a especificacao OpenAPI.
- Payload validado com Zod e erro `400` detalhado em caso invalido.
- BullMQ enfileira job `meta-ad-takedown`.
- Redis roda localmente via Docker Compose.
Expand Down
195 changes: 193 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
"@nestjs/config": "^4.0.0",
"@nestjs/core": "^11.0.0",
"@nestjs/platform-express": "^11.0.0",
"@nestjs/swagger": "^11.4.4",
"@scalar/nestjs-api-reference": "^1.1.16",
"bullmq": "^5.0.0",
"helmet": "^8.0.0",
"ioredis": "^5.0.0",
Expand Down
33 changes: 33 additions & 0 deletions src/docs/openapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { INestApplication } from "@nestjs/common";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { apiReference } from "@scalar/nestjs-api-reference";

export function setupOpenApiDocs(app: INestApplication): void {
const config = new DocumentBuilder()
.setTitle("FURY Click Hero API")
.setDescription(
"Mini-API para receber violacoes de anuncios, validar payloads, enfileirar jobs BullMQ e processar takedowns com uma chamada HTTP externa simulando a Meta Ads API."
)
.setVersion("0.1.0")
.addTag("Health", "Status operacional da API")
.addTag("Takedown jobs", "Webhook de violacao e consulta de jobs")
.build();

const document = SwaggerModule.createDocument(app, config, {
operationIdFactory: (_controllerKey: string, methodKey: string) => methodKey
});

SwaggerModule.setup("openapi", app, document, {
ui: false,
raw: ["json"],
jsonDocumentUrl: "openapi.json"
});

app.use(
"/docs",
apiReference({
theme: "purple",
url: "/openapi.json"
})
);
}
Loading
Loading