API REST assíncrona para monitoramento, ingestão e jurimetria de processos judiciais, integrada à API Pública do DataJud (CNJ).
Este repositório e o dashboard juris-sync-web existem exclusivamente para o portfólio técnico. São artefatos para avaliação em ambiente local (clone + run), não um serviço público em produção.
- Hub / case study: maria-portfolio · site
- Mock (padrão, sem chave) ou DataJud real (chave própria do testador) - ver guia do testador
A intenção do projeto é demonstrar como documentar e testar durante o desenvolvimento, não só o resultado final.
- Implementação - camadas bem definidas, persistência idempotente, integração com o DataJud, logs estruturados, migrações versionadas e pipeline de CI.
- Vibe docs - requisitos, regras de negócio, histórias de usuário, cenários BDD e rastreabilidade requisito → código → teste em
docs/requisitos.md, escritos em paralelo ao código (documentação viva, não pós-facto). - Testes no fluxo de desenvolvimento - suíte em camadas (unitário, API, mock HTTP, reconciliação, integração e contrato) guiando refatorações e evolução do domínio, com cobertura mínima de 85% no CI.
📄 Documentação de requisitos: docs/requisitos.md
📋 Case study (portfólio): mariahilmar-portfolio.vercel.app · narrativa em ../maria-portfolio/docs/case-study-juris-sync.md quando clonado com o hub no workspace local
🖥️ Dashboard (Next.js): juris-sync-web · Guia do testador (clone local, mock vs dados reais)
Qualquer pessoa pode baixar este repositório, configurar o ambiente e validar a API - com ou sem credencial do CNJ.
| Modo | DATAJUD_API_KEY |
Comportamento |
|---|---|---|
| Mock (padrão) | vazio | Dados determinísticos gerados a partir do CNJ; ideal para demo e CI local |
| Real (DataJud) | chave CNJ | Consulta a API Pública DataJud; use CNJs reais |
O endpoint /health indica o modo ativo: services.datajud_api = mock_mode ou configured.
Fluxo recomendado:
- Clone
juris-syncejuris-sync-web - Suba a API (seção Execução local)
- (Opcional mock) Rode
python scripts/seed_demo.pypara jurimetria mais rica - (Opcional real) Preencha
DATAJUD_API_KEYno.enve sincronize CNJs reais - Suba o dashboard e acesse http://localhost:3000
Guia completo para testadores: juris-sync-web/docs/guia-do-testador.md
- FastAPI + SQLAlchemy 2.0 async - I/O não bloqueante com
asyncpg/aiosqlite - Motor DataJud - integração real com API do CNJ + mock determinístico para desenvolvimento sem credenciais
- Sincronização idempotente - evita duplicar processos e movimentações
- RAG em memória - normalização de classe, assunto e tribunal antes da validação Pydantic
- Alembic - versionamento de schema (
processos,movimentacoes) - Structlog - logs legíveis em dev, JSON em produção
- 43 testes em 5 camadas - unitário, API (ASGI), mock HTTP (
respx), reconciliação de sync, integração (Testcontainers) e contrato OpenAPI (Schemathesis) - cobertura ≥ 85% - Documentação de requisitos - regras de negócio, histórias de usuário, cenários BDD e rastreabilidade requisito → código → teste em
docs/requisitos.md - GitHub Actions - lint (Ruff, Black, Mypy) + testes (unitário + integração + contrato) em cada push/PR
graph TD
Client[Cliente / Frontend] -->|HTTP| API[FastAPI]
API --> Router["/api/v1/processos"]
Router --> Service[JurisSyncService]
Service --> ClientDJ[DataJudClient]
ClientDJ -->|HTTPS + APIKey| DataJud[API Pública CNJ]
ClientDJ -.->|fallback| Mock[Mock determinístico]
Service --> RAG[DataJudRAGEnricher]
Service --> DB[(PostgreSQL / SQLite)]
O dashboard de jurimetria e processos está no repositório juris-sync-web (Next.js + React + TypeScript), consumindo esta API via HTTP.
Subir API + dashboard localmente:
# Terminal 1 - API
cd juris-sync
.\.venv\Scripts\Activate.ps1
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
# Terminal 2 - Dashboard
cd ..\juris-sync-web
npm install
npm run dev- API: http://localhost:8000 (Swagger em
/docs) - Dashboard: http://localhost:3000
Em desenvolvimento, BACKEND_CORS_ORIGINS=* (padrão) já permite o frontend. Em produção, liste a origem do deploy Vercel do dashboard.
Teste local: quem clona os dois repositórios pode rodar API + dashboard sem deploy. Modo mock (sem chave CNJ) ou dados reais (com DATAJUD_API_KEY) - ver Guia do testador.
- Extração -
DataJudClientconsulta o tribunal correto (api_publica_{alias}/_search) ou gera mock a partir do CNJ - Enriquecimento - RAG recupera contexto jurídico e normaliza campos
- Validação - Pydantic v2 valida formato CNJ e tipos
- Persistência - upsert do processo + inserção apenas de movimentações novas
| Camada | Tecnologia |
|---|---|
| API | FastAPI, Uvicorn |
| ORM | SQLAlchemy 2.0 (async) |
| Migrações | Alembic |
| Validação | Pydantic v2, pydantic-settings |
| HTTP externo | httpx |
| Logs | structlog |
| Testes | pytest, pytest-asyncio, pytest-cov |
| Qualidade | Ruff, Black, Mypy |
| Container | Docker, Docker Compose |
| Tabela | Campos principais |
|---|---|
processos |
numero_cnj (único), tribunal, classe, assunto, grau |
movimentacoes |
processo_id (FK), data_hora, descricao, codigo_movimento |
| Método | Rota | Descrição |
|---|---|---|
GET |
/health |
Status da API, banco e modo DataJud |
POST |
/api/v1/processos/sync |
Sincroniza processo pelo número CNJ |
GET |
/api/v1/processos/ |
Lista processos paginados (items, total, limit, offset) |
GET |
/api/v1/processos/{id} |
Detalhe com movimentações |
GET |
/api/v1/processos/stats/por-tribunal |
Jurimetria por tribunal |
GET |
/api/v1/processos/stats/por-assunto |
Jurimetria por assunto |
Documentação interativa: GET /docs (Swagger UI) ou GET /redoc (ReDoc).
curl -X POST http://localhost:8000/api/v1/processos/sync \
-H "Content-Type: application/json" \
-d '{"numero_cnj": "0001234-56.2023.8.15.0001", "grau": 1}'A pasta postman/ contém uma coleção para exploração manual e demonstração da API - não faz parte da suíte automatizada de testes (essa fica em tests/, veja a seção Testes).
| Arquivo | Conteúdo |
|---|---|
JurisSync.postman_collection.json |
Requisições para todos os endpoints, com casos positivos e negativos (422, 404) e testes JS embutidos |
JurisSync-Local.postman_environment.json |
Variáveis para apontar para http://localhost:8000 |
Como usar:
- Importe os dois arquivos no Postman (
File > Import) - Selecione o environment JurisSync - Local
- Rode Sincronizar Processo com o DataJud primeiro - o
processo_idretornado é salvo automaticamente na variável de coleção e reutilizado por Obter Detalhes do Processo
Uso pretendido: onboarding, debug manual e smoke test pontual - não substitui pytest/Schemathesis/Testcontainers, que são a base de qualidade automatizada do projeto.
- Python 3.12+
- (Opcional) Docker e Docker Compose
- (Opcional) Chave da API Pública DataJud - solicitar no CNJ - necessária apenas para dados reais; sem chave, o modo mock funciona out of the
Sem DATAJUD_API_KEY, a API opera em modo mock: gera processos e movimentações plausíveis a partir do número CNJ (determinístico - o mesmo CNJ sempre produz os mesmos dados).
Para popular a base local com processos em várias UFs (mapa e gráficos do dashboard):
python scripts/seed_demo.pyO seed cobre os 27 tribunais de justiça estaduais com 116 processos e volumes assimétricos por UF (ex.: SP 15, RJ 12, AC/AP 1) para o mapa choropleth ficar legível. Isso não substitui o teste com DataJud real - são cenários complementares.
git clone https://github.com/MariaHilmar/juris-sync.git
cd juris-sync
python -m venv .venv
.venv\Scripts\Activate.ps1 # Windows
# source .venv/bin/activate # Linux/macOS
pip install -r requirements-dev.txt
copy .env.example .env # ou: cp .env.example .env
alembic upgrade head
python app/main.pyAPI disponível em http://localhost:8000
| Variável | Descrição | Padrão |
|---|---|---|
DATABASE_URL |
Conexão async (SQLite ou PostgreSQL) | sqlite+aiosqlite:///./juris_sync.db |
DATAJUD_API_KEY |
Chave API CNJ. Vazio = modo mock (demo local sem credencial). Preenchida = consulta real ao DataJud | - |
DATAJUD_API_URL |
Base da API pública | https://api-publica.datajud.cnj.jus.br |
ENV |
development / production |
development |
docker compose up --buildEm outro terminal, com DATABASE_URL apontando para o Postgres do compose:
alembic upgrade headO projeto conta com 43 testes automatizados organizados em 5 camadas, cobrindo desde regras de negócio isoladas até fuzzing de contrato OpenAPI e integração com PostgreSQL real.
- Testes unitários - validam o comportamento isolado de
sync_service,datajud_client, RAG e schemas Pydantic. - Testes de API - disparam requisições HTTP reais (via
httpx.AsyncClient+ASGITransport) contra os endpoints FastAPI, com banco SQLite em memória isolado por teste. - Mock de API externa - intercepta a camada HTTP real com
respx, validando o contrato exato da chamada ao DataJud (headers, payload) e os cenários de fallback (404, 500, timeout). - Reconciliação de sincronização - garante fidelidade dos dados persistidos vs. fonte externa, atomicidade em falhas parciais e ausência de movimentações órfãs.
- Integração e contrato - PostgreSQL real via Testcontainers (com migrations reais do Alembic) e fuzzing do schema OpenAPI via Schemathesis/Hypothesis.
| Categoria | Ferramenta |
|---|---|
| Framework de testes | pytest + pytest-asyncio |
| Cobertura | pytest-cov |
| Modo watch | pytest-watch |
| Cliente HTTP para testes de API | httpx (AsyncClient + ASGITransport) |
| Mocks/dados de teste | factory-boy, respx (mock de HTTP) |
| Banco real para integração | Testcontainers (PostgreSQL) |
| Contract testing / fuzzing | Schemathesis (Hypothesis) |
| Type checking | Mypy (Pydantic plugin) |
Na raiz do projeto, com o ambiente virtual ativado:
# Rodar toda a suíte padrão (unitário + API + mock + reconciliação)
python -m pytest
# Rodar em modo watch (reexecuta automaticamente a cada alteração de arquivo)
ptw
# Gerar relatório de cobertura no terminal
python -m pytest --cov=app --cov-report=term-missing
# Gerar relatório de cobertura em HTML (abre htmlcov/index.html no navegador)
python -m pytest --cov=app --cov-report=htmlA suíte padrão usa SQLite em memória com savepoints para isolar testes que fazem commit, e falha automaticamente se a cobertura ficar abaixo de 85% (configurado em pyproject.toml).
Testes de integração (PostgreSQL real) e de contrato (OpenAPI) exigem Docker e são pulados por padrão. Para executá-los:
python -m pytest -m integration --no-cov # exige Docker rodando localmente
python -m pytest -m contract --no-covtests/test_api.py::test_api_health_endpoint PASSED [ 3%]
tests/test_api.py::test_api_sync_process_endpoint PASSED [ 6%]
tests/test_api.py::test_api_sync_invalid_cnj_returns_422 PASSED [ 9%]
tests/test_api.py::test_api_list_and_detail_processes PASSED [ 12%]
tests/test_api.py::test_api_detail_returns_404_for_not_found PASSED [ 15%]
tests/test_api.py::test_api_jurimetria_stats_endpoints PASSED [ 18%]
tests/test_datajud_client.py::test_mock_client_generates_consistent_data PASSED [ 21%]
tests/test_datajud_client_contract.py::test_fetch_from_api_sends_expected_request_contract PASSED [ 46%]
tests/test_rag_enricher.py::test_rag_enricher_retrieves_context_and_normalizes_fields PASSED [ 59%]
tests/test_sync_reconciliation.py::test_reconciliation_rolls_back_completely_on_partial_failure PASSED [ 84%]
tests/test_sync_service.py::test_sync_new_movement_adds_only_the_new_one PASSED [100%]
---------------------------- tests coverage -----------------------------
Name Stmts Miss Cover
------------------------------------------------------------------
app\services\sync_service.py 60 0 100%
app\services\datajud_client.py 104 3 97%
app\schemas\process.py 61 3 95%
app\models\process.py 34 2 94%
------------------------------------------------------------------
TOTAL 574 58 90%
Required test coverage of 85% reached. Total coverage: 89.90%
====================== 32 passed, 11 deselected in 1.73s ======================
💡 Nota de cobertura: o projeto mantém 89,9% de cobertura na suíte padrão, com portão de qualidade (
--cov-fail-under=85) que falha o CI automaticamente se a cobertura cair abaixo de 85%.
| Camada | O que valida | Marcador |
|---|---|---|
| Unitário/API | Regras de negócio, schemas, endpoints (SQLite in-memory) | padrão |
| Mock de API externa | Contrato HTTP (headers, payload) e fallback do cliente DataJud, via respx |
padrão |
| Reconciliação de sync | Fidelidade dos dados persistidos vs. fonte externa, atomicidade e ausência de órfãos | padrão |
| Integração | PostgreSQL real via Testcontainers, incluindo migrations reais do Alembic | integration |
| Contrato OpenAPI | Fuzzing do schema OpenAPI com Schemathesis (Hypothesis) | contract |
Regras de negócio e critérios de aceite testados por cada camada estão documentados em docs/requisitos.md.
O workflow .github/workflows/ci.yml executa em push/PR para main:
| Job | Etapas |
|---|---|
| Lint | ruff check + black --check |
| Test | pytest com cobertura (suíte unitária/API) |
| Integration | Testes com PostgreSQL real (Testcontainers) + contract testing (Schemathesis) |
- Revisão humana em pull requests (template em
.github/pull_request_template.md) - Cursor Bugbot em PRs com regras do domínio em
.cursor/BUGBOT.md(idempotência, reconciliação, contrato DataJud) - Ative o Bugbot no dashboard do Cursor para o repositório
MariaHilmar/juris-sync
Este projeto foi desenvolvido com ferramentas de IA generativa sob a metodologia de Especificação Direcionada (SDD): requisitos, regras de negócio e cenários BDD foram definidos antes ou em paralelo à implementação (docs/requisitos.md), e o código passou por revisão humana rigorosa (code review, testes em 5 camadas com ~90% de cobertura). A IA acelerou boilerplate e documentação; a idempotência, reconciliação e contratos HTTP são validados pela suíte de testes e pela rastreabilidade requisito → código → teste documentada em docs/.
juris-sync/
├── app/
│ ├── api/ # Rotas FastAPI
│ ├── core/ # Config, database, logging
│ ├── models/ # ORM SQLAlchemy
│ ├── schemas/ # Pydantic
│ ├── services/ # DataJud, sync, RAG
│ └── main.py
├── alembic/ # Migrações
├── tests/ # Pytest (unitário, mock, reconciliação, integração, contrato)
├── postman/ # Coleção Postman - uso manual/demo, não faz parte do CI
├── docs/ # Requisitos, regras de negócio, histórias de usuário, BDD
├── .github/workflows/ # CI
├── docker-compose.yml
├── Dockerfile
└── pyproject.toml # Black, Ruff, Pytest
| Sprint | Entrega | Status |
|---|---|---|
| 1 | Setup e boilerplate | ✅ |
| 2 | Banco + Alembic | ✅ |
| 3 | Motor DataJud | ✅ |
| 4 | Testes Pytest | ✅ |
| 5 | README + CI/CD | ✅ |
Este projeto está licenciado sob a Licença MIT - veja o arquivo LICENSE para detalhes.