mirror of
https://github.com/domfelipe/fraudshield.git
synced 2026-08-07 12:36:52 +00:00
Stack: Python 3.12/FastAPI + React 19/TypeScript + PostgreSQL + Redis. 6 artifacts: plan.md, research.md, data-model.md, api.yaml (OpenAPI), quickstart.md, updated AGENTS.md. Constitution check: 6/6 PASS.
5.2 KiB
5.2 KiB
Quickstart: FraudShield
Feature: 001-fraud-detection-engine
Pré-requisitos
- Docker & Docker Compose
- Python 3.12+
- Node.js 20+
uv(Python package manager)
Setup Local (Dev)
# 1. Clone e entre no projeto
git clone <repo-url> fraudshield
cd fraudshield
# 2. Suba os serviços de infra
docker compose up -d postgres redis
# 3. Backend
cd backend
uv sync # Instala dependências
uv run alembic upgrade head # Cria tabelas
uv run python -m fraudshield.seed # Popula regras iniciais + dados de teste
uv run uvicorn fraudshield.main:app --reload --port 8000
# 4. Frontend (outro terminal)
cd frontend
npm install
npm run dev # http://localhost:5173
# 5. Testes
cd backend && uv run pytest # Backend
cd frontend && npm test # Frontend
Infraestrutura Docker
# docker-compose.yml (visão geral)
services:
postgres:
image: postgres:16
environment:
POSTGRES_DB: fraudshield
POSTGRES_USER: fraudshield
POSTGRES_PASSWORD: fraudshield_dev
ports: ["5432:5432"]
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports: ["6379:6379"]
Credenciais de Teste
| Perfil | Usuário | Senha |
|---|---|---|
| Analista | analista@fraudshield.local |
fraudshield123 |
| Administrador | admin@fraudshield.local |
fraudshield123 |
| Sênior | senior@fraudshield.local |
fraudshield123 |
Fluxo de Teste Manual
1. Ingerir uma transação suspeita
curl -X POST http://localhost:8000/api/v1/transactions/ingest \
-H "Content-Type: application/json" \
-H "X-API-Key: dev-api-key" \
-d '{
"external_id": "txn_test_001",
"amount": 15000.00,
"merchant_name": "Loja Desconhecida Ltda",
"merchant_category": "joalheria",
"latitude": -23.5505,
"longitude": -46.6333,
"customer_id": "tok_cust_001",
"channel": "web",
"transaction_at": "2026-05-11T03:15:00-03:00"
}'
2. Verificar alertas pendentes
curl http://localhost:8000/api/v1/alerts?status=pending \
-H "Authorization: Bearer <jwt_token>"
3. Decidir sobre um alerta
curl -X POST http://localhost:8000/api/v1/alerts/<alert_id>/decide \
-H "Authorization: Bearer <jwt_token>" \
-H "Content-Type: application/json" \
-d '{"decision": "confirmed"}'
4. Criar uma regra
curl -X POST http://localhost:8000/api/v1/rules \
-H "Authorization: Bearer <admin_jwt_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Valor noturno elevado",
"description": "Detecta transações acima de R$ 1000 entre 22h e 06h",
"condition": "amount > 1000 and hour >= 22 or hour <= 6",
"weight": 25
}'
5. Testar regra contra dados históricos
curl -X POST http://localhost:8000/api/v1/rules/<rule_id>/test \
-H "Authorization: Bearer <admin_jwt_token>" \
-H "Content-Type: application/json" \
-d '{"days_back": 90}'
6. Dashboard
curl http://localhost:8000/api/v1/dashboard/metrics?period=24h \
-H "Authorization: Bearer <jwt_token>"
Estrutura do Projeto
fraudshield/
├── backend/
│ ├── fraudshield/
│ │ ├── main.py # FastAPI app + routers
│ │ ├── config.py # Settings via pydantic-settings
│ │ ├── models/ # SQLAlchemy models
│ │ │ ├── transaction.py
│ │ │ ├── rule.py
│ │ │ ├── alert.py
│ │ │ └── audit.py
│ │ ├── engine/ # Rule engine
│ │ │ ├── evaluator.py # Core evaluation logic
│ │ │ ├── rules/ # Individual rule implementations
│ │ │ └── explainer.py # Explanation generation
│ │ ├── api/ # Route handlers
│ │ │ ├── transactions.py
│ │ │ ├── alerts.py
│ │ │ ├── rules.py
│ │ │ └── dashboard.py
│ │ ├── services/ # Business logic
│ │ ├── auth.py # JWT + OAuth2
│ │ └── seed.py # Dev data seeder
│ ├── alembic/ # DB migrations
│ ├── tests/
│ │ ├── unit/
│ │ ├── integration/
│ │ └── contract/
│ └── pyproject.toml
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ ├── pages/
│ │ ├── hooks/
│ │ ├── api/ # Generated API client
│ │ └── App.tsx
│ ├── tests/
│ └── package.json
├── docker-compose.yml
└── specs/
Regras Iniciais (Seed)
O seed popula 5 regras padrão:
| Regra | Condição | Peso |
|---|---|---|
| Valor atípico | amount > customer.avg_amount_30d * 3 |
30 |
| Local incomum | distance(current_location, customer.home_location) > 100km |
25 |
| Horário suspeito | hour >= 0 and hour <= 5 and amount > 500 |
20 |
| Categoria rara | merchant_category not in customer.common_categories |
15 |
| Canal novo | channel not in customer.common_channels |
10 |
Threshold padrão do sistema: 70/100.