Microsserviço de processamento do Hackathon FIAP. Consome analysis.requested do SQS, baixa o diagrama do S3, executa o pipeline de IA em duas etapas (Gemini Vision + Groq) e publica analysis.completed (Event-Carried State Transfer) com o payload completo.
🚨 Faz parte do Hackathon Integrado IADT + SOAT da FIAP (entrega 2026-05-27). Visão geral, ADRs e diagrama:
fiap-hackathon-infra.
SQS analysis.requested
│
▼
[processing]
1. existsByAnalysisId? (idempotência)
2. publish analysis.processing.started
3. GET s3://bucket/raw/{uuid}
4. (PDF? renderiza 1ª página em PNG via pdf2pic)
5. pipeline 2 etapas:
Gemini Vision → ComponentsExtraction (Zod validated)
Groq Llama 3.3 → RisksAndRecommendations (Zod validated)
retry 3x exponential backoff + fallback Mock
6. INSERT analysis_results (MongoDB)
7. publish analysis.completed (payload completo)
│
▼
SQS analysis.completed → consumido pelo `report`
Em caso de falha permanente: publica analysis.failed com reason ∈ {DOWNLOAD_FAILED, SCHEMA_VALIDATION_FAILED, AI_PROVIDER_EXHAUSTED, TIMEOUT, INTERNAL} e a mensagem volta ao SQS para retry; após 3 tentativas vai para a DLQ.
- Framework: NestJS 11 + TypeScript
- Arquitetura: Clean Architecture (Interface / Application / Domain / Infrastructure)
- DB: MongoDB (Mongoose) — outputs de IA são semi-estruturados
- Mensageria: AWS SQS (consumer + publisher)
- Object storage: AWS S3 (download via GetObject)
- PDF rendering:
pdf2pic(depende de GraphicsMagick + Ghostscript no runtime) - LLM providers: Strategy Pattern — Gemini 2.5 Flash + Groq Llama 3.3 70B + Mock (default)
- Guardrails: Zod nos outputs de cada etapa, retry com exponential backoff, fallback Mock
- Logger: Pino estruturado com redação de PII
- Observabilidade: Datadog APM (
dd-trace)
Variáveis críticas:
| Variável | Default dev | Para produção |
|---|---|---|
MONGO_URI |
local docker-compose | MongoDB Atlas |
SQS_ANALYSIS_REQUESTED_URL |
LocalStack | URL real |
SQS_ANALYSIS_COMPLETED_URL |
LocalStack | URL real |
SQS_ANALYSIS_FAILED_URL |
LocalStack | URL real |
LLM_VISION_PROVIDER |
mock |
gemini |
LLM_TEXT_PROVIDER |
mock |
groq |
GEMINI_API_KEY |
(vazio) | obrigatória se gemini |
GROQ_API_KEY |
(vazio) | obrigatória se groq |
Ver .env.example para a lista completa.
fiap-hackathon-bfffiap-hackathon-upload-orchestrationfiap-hackathon-reportfiap-hackathon-lambda-authfiap-hackathon-infra
src/
├── shared/ # Schemas Zod, LLM Strategy completo, logger, erros
├── domain/
│ └── entities/analysis-result.entity.ts
├── application/
│ ├── ports/ # ObjectStorage, EventPublisher, LlmPipelinePort,
│ │ # PdfRenderer, AnalysisResultRepository, IdGenerator
│ └── use-cases/
│ └── process-analysis.use-case.ts
├── infrastructure/
│ ├── persistence/ # Mongoose schema + repository
│ ├── storage/ # S3 GetObject adapter
│ ├── messaging/ # SQS publisher (started/completed/failed)
│ ├── llm/ # Wrapper sobre o LlmPipeline do shared
│ ├── pdf/ # pdf2pic adapter (PDF → PNG)
│ ├── id/ # uuid adapter
│ └── config/processing.config.ts
├── interface/
│ ├── consumer/ # Worker que faz polling do SQS
│ │ └── analysis-requested.consumer.ts
│ └── http/controllers/health.controller.ts
├── app.module.ts
└── main.ts
Pré-requisitos: o stack do fiap-hackathon-infra precisa estar de pé (make up lá no repo de infra).
# 1. Instalar deps
npm install
# 2. Configurar env (mock provider por padrão = sem chave real)
cp .env.example .env
# 3. Subir o serviço
npm run start:devnpm test # unit (Jest, gate de cobertura 70%)
npm run test:int # integration (testcontainers Mongo + LocalStack)A imagem inclui GraphicsMagick + Ghostscript (runtime) porque o pdf2pic depende deles para rasterizar PDFs.
docker build -t fiap-hackathon-processing:dev .
docker run --rm -p 3002:3002 --env-file .env fiap-hackathon-processing:devTodas seguem a ADR-002, em especial:
- D5 — MongoDB para outputs semi-estruturados de IA
- D6 — Event-Carried State Transfer no
analysis.completed - D8 — Strategy Pattern multi-provider com Mock como fallback
- D9 — Pipeline de IA em duas etapas justificadas (vision → text)
- D14 — pirâmide pragmática de testes
- D15 — defesa contra prompt injection (no system prompt) + Zod nos outputs + temperature 0.2