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
21 changes: 17 additions & 4 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
# Controle de versão
# Controle de versão e CI
.git/
.gitignore
.github/

# Ambientes virtuais e cache do Python
.venv/
venv/
__pycache__/
*.pyc
*.pyo
*.pyd
.pytest_cache/
.ipynb_checkpoints/

# Variáveis de ambiente sensíveis
# Segredos
.env

# Dados brutos pesados que não devem ir para a imagem da aplicação
data/raw/
# Dados brutos e modelo: entram por volume, nunca pela imagem
data/raw/
modelos_salvos/*.joblib

# O que a aplicação não usa para rodar (deixa a imagem menor e o build mais rápido)
notebooks/
tests/
skills/
infra/
docs/figuras/
docs/bpmn/
iniciar.ps1
38 changes: 37 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,46 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

# O mesmo SQL que o Docker roda na 1ª criação do banco, em ordem.
# Quebrou um CREATE, uma view ou uma regra da tabela de decisões → CI vermelha.
- name: Aplicar o esquema do banco (db/0*.sql)
env:
PGPASSWORD: postgres
run: |
for f in db/0*.sql; do
echo "== $f"
psql -h localhost -U postgres -d auditor_db -v ON_ERROR_STOP=1 -q -f "$f"
done

- name: Conferir as regras da tabela de decisões (teste SQL do Marcos)
env:
PGPASSWORD: postgres
run: psql -h localhost -U postgres -d auditor_db -v ON_ERROR_STOP=1 -f db/testes/05_teste_decisoes.sql

# Validações
- name: Rodar Bateria de Testes do Pytest
env:
# Aponta os testes para o banco temporário criado no passo 2
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/auditor_db
run: |
pytest tests/ -v
pytest tests/ -v

build-da-imagem:
name: Build da imagem Docker
runs-on: ubuntu-latest
steps:
- name: Clonar o repositório
uses: actions/checkout@v4

- name: Configurar o Buildx
uses: docker/setup-buildx-action@v3

# Garante que o Dockerfile continua construindo. Cache do GitHub: só o 1º build é lento.
- name: Construir a imagem (sem publicar)
uses: docker/build-push-action@v6
with:
context: .
push: false
tags: auditor-preco-justo:ci
cache-from: type=gha
cache-to: type=gha,mode=max
30 changes: 20 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
# syntax=docker/dockerfile:1
# Imagem única do Auditor de Preço Justo: a mesma serve a API (padrão) e o painel
# (o docker-compose troca o comando). Ordem pensada para o cache: o que muda pouco
# (sistema e bibliotecas) vem antes do código, que muda sempre.
FROM python:3.14-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1

WORKDIR /app

#instalação de pacotes e libs
RUN apt-get update && apt-get install -y \
# Pacotes do sistema para compilar o psycopg2
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

# requirements-genai.txt inclui o requirements.txt + busca nas normas (sentence-transformers,
# torch CPU, pgvector) e o cliente do Gemini, usados pelo parecer na API.
# Bibliotecas: requirements-genai.txt inclui o requirements.txt + busca nas normas
# (sentence-transformers, torch CPU, pgvector), Gemini e LangChain.
# O cache do pip fica guardado entre builds (BuildKit): se um requirement mudar,
# só ele é baixado de novo, e não o PyTorch inteiro (~1 GB).
COPY requirements.txt requirements-genai.txt ./
RUN pip install --no-cache-dir -r requirements-genai.txt
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements-genai.txt

#copia codigo fonte do projeto local
# Código do projeto (o .dockerignore deixa de fora dados, notebooks, testes e segredos)
COPY . .

EXPOSE 8000
EXPOSE 8000 8501

#p/ definir o comando que sera iniciado quando o container executar
#servidor uvicorn web, rodando fastapi, na porta 8000 com conexao de fora do container
CMD ["uvicorn", "src.api.main:app", "--host", "0.0.0.0", "--port", "8000"]
# Padrão: API FastAPI na porta 8000, aceitando conexões de fora do container
CMD ["uvicorn", "src.api.main:app", "--host", "0.0.0.0", "--port", "8000"]
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ tests/ testes

Pré-requisitos: Git, Python 3.14 e Docker Desktop.

**Atalho (Windows):** com o banco já carregado (passos 2 a 5 abaixo, uma vez), use o `iniciar.ps1`:

| Comando | O que faz |
| --- | --- |
| `.\iniciar.ps1` | confere `.env` e modelo, sobe o banco, aplica a tabela de decisões, indexa as normas (se faltar), sobe API e painel e abre o navegador. Constrói a imagem só se ela não existir. |
| `.\iniciar.ps1 -Build` | o mesmo, reconstruindo a imagem (mudou código ou requirements) |
| `.\iniciar.ps1 -Parar` | para tudo; os dados do banco ficam guardados |

O primeiro build leva alguns minutos (PyTorch); os seguintes reaproveitam o cache e uma imagem única serve API e painel.

1. Clone o repositório e instale as dependências:
```
git clone https://github.com/yaMimis/Auditor-Project.git
Expand Down Expand Up @@ -103,16 +113,15 @@ Pré-requisitos: Git, Python 3.14 e Docker Desktop.

**Normas do parecer** (busca no pgvector), uma vez, com `pip install -r requirements-genai.txt`:
```
python -m genai.src.dividir
python -m genai.src.indexar
python genai/src/indexar.py
```
Sem esse passo o parecer funciona, mas sai sem fontes.

6. **API e painel.** Coloque `pacote_prever_v1.joblib` em `modelos_salvos/` (fora do Git; peça ao Samuel) e suba:
```
docker compose up --build api streamlit
```
O primeiro build demora mais: a imagem instala o PyTorch (CPU) para a busca nas normas.
O primeiro build demora mais: a imagem instala o PyTorch (CPU) para a busca nas normas. Depois, `docker compose up -d` sobe sem reconstruir; use `--build` só quando mudar código ou requirements.
- Painel: http://localhost:8501 (sem o modelo, use os exemplos da aba de revisão)
- API: http://localhost:8000/docs (`GET /` informa se o modelo foi carregado)
- Para os dados da carteira, o painel lê `docs/resultados/carteira_auditoria.csv` e `equidade.json`.
Expand All @@ -132,6 +141,8 @@ Pré-requisitos: Git, Python 3.14 e Docker Desktop.
- [`notebooks/dados/01_eda.ipynb`](notebooks/dados/01_eda.ipynb): análise exploratória e as figuras dos slides (`docs/figuras/`).
- [`docs/bpmn/`](docs/bpmn/): processo em BPMN 2.0.
- [`genai/FORMATO_JSON.md`](genai/FORMATO_JSON.md) e [`genai/REGRAS_PARECER.md`](genai/REGRAS_PARECER.md): contrato e regras do parecer.
- [`docs/ROTEIRO_DEMO.md`](docs/ROTEIRO_DEMO.md): roteiro da demo, plano B e perguntas prováveis.
- [`infra/`](infra/README.md): o mesmo ambiente em Terraform (provider Docker, local, sem custo).
- [`skills/`](skills/README.md): guia do projeto por setor (estrutura, ambiente, dados, modelo, juro justo, parecer, API, painel, governança).

## Governança e ética
Expand Down
32 changes: 26 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#docker compose build (para rodar as imagens)
#docker compose up -d (para rodar o container e colocar o app no ar)
# Auditor de Preço Justo: banco (PostgreSQL + pgvector), API (8000) e painel (8501).
# docker compose up -d sobe tudo (usa a imagem já construída)
# docker compose up -d --build reconstrói a imagem antes (mudou código ou requirements)
# docker compose down para tudo (os dados do banco ficam no volume)
# No Windows, o atalho é o .\iniciar.ps1.

services:
postgres:
image: pgvector/pgvector:pg16
Expand All @@ -12,11 +16,17 @@ services:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./db:/docker-entrypoint-initdb.d
- ./db:/docker-entrypoint-initdb.d # só na 1ª criação do volume (subpastas são ignoradas)
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d auditor_db"]
interval: 5s
timeout: 5s
retries: 20
restart: unless-stopped

api:
build: .
image: auditor-preco-justo:latest # a mesma imagem serve o painel: um build só
container_name: auditor_api
ports:
- "8000:8000"
Expand All @@ -29,11 +39,20 @@ services:
- ./modelos_salvos:/app/modelos_salvos # pacote_prever_v1.joblib (fora do Git)
- cache_modelos_hf:/root/.cache/huggingface # modelo de busca nas normas: baixa uma vez só
depends_on:
- postgres
postgres:
condition: service_healthy
healthcheck:
# A 1ª subida baixa o modelo de busca nas normas (~0,5 GB): por isso o start_period longo.
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/', timeout=5)"]
interval: 10s
timeout: 10s
retries: 6
start_period: 180s
restart: unless-stopped

streamlit:
build: .
image: auditor-preco-justo:latest # construída pelo serviço api
pull_policy: never
container_name: auditor_streamlit
command: streamlit run src/app/main.py --server.port=8501 --server.address=0.0.0.0
ports:
Expand All @@ -43,7 +62,8 @@ services:
volumes:
- ./docs/resultados:/app/docs/resultados # carteira_auditoria.csv e equidade.json do lote
depends_on:
- api
api:
condition: service_healthy
restart: unless-stopped

volumes:
Expand Down
61 changes: 61 additions & 0 deletions docs/ROTEIRO_DEMO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Roteiro da demo — Auditor de Preço Justo

**Versão:** 1.0 · **Data:** 10/11/2026 · **Responsável:** Yasmin (App e infraestrutura) · **Revisor:** grupo · **Status:** rascunho para o ensaio

Demo ao vivo de cerca de **8 minutos**, no dia 15/11, seguida da mesma sequência gravada em vídeo (plano B). Cada bloco diz o que mostrar na tela, a frase-chave e o ponto do guia que ele prova.

---

## 1. Antes de começar (no dia, 30 min antes)

- [ ] Docker Desktop aberto; rodar `.\iniciar.ps1` e esperar o "Pronto".
- [ ] Em http://localhost:8000/: `modelo_carregavel: true` e `banco_disponivel: true`.
- [ ] Fazer **uma auditoria de aquecimento** pelo formulário: a 1ª chamada ao Gemini e à busca nas normas é a mais lenta.
- [ ] Preencher "Analista responsável" no topo da seção de auditoria.
- [ ] Navegador em tela cheia, zoom em 90% a 100%, abas abertas: painel (8501) e documentação da API (8000/docs).
- [ ] Vídeo gravado aberto em outra janela, pronto para o plano B.

## 2. Sequência

| # | Tempo | Na tela | Frase-chave | Prova |
|---|---|---|---|---|
| 1 | 0:00 | Capa do painel | "Para cada contrato: qual o risco, se o juro é justo para esse risco e se clientes de mesmo risco pagam diferente. Quem decide é o analista." | Ideia e enquadramento |
| 2 | 0:45 | Aba **Revisão de contrato** → formulário (3 etapas) → **Executar auditoria** | "Gênero e idade ficam registrados só para auditoria: não entram no modelo nem no parecer." | Governança: atributos sensíveis só auditam |
| 3 | 1:45 | Cartões, régua e motivos do resultado | "O juro justo vem do fluxo de caixa: custo do dinheiro da época, perda esperada e margem da safra, com margem de incerteza do bootstrap." | Modelo e juro justo |
| 4 | 2:45 | Parecer "Gerado por IA", fontes e referência de mercado do BC | "A IA só escreve. Recomendação e números vêm do código, e cada número do texto é conferido; se falhar, entra o template." | GenAI com checagem |
| 5 | 3:45 | **Caso de exemplo → Acima do justo · 98ffaaa4-0b86** (faixa D: cobrado 39,0%, justo 34,0%, margem 31,7%–36,8%) | "Indício a investigar, não conclusão." | Linguagem de indício |
| 6 | 4:30 | **Caso de exemplo → Revisão manual · 1cb66730-5f46** | "Dados fora da faixa de treino: o sistema não arrisca um número e devolve ao analista." | Revisão manual |
| 7 | 5:00 | Decisão do analista: justificativa + **Revisar preço** com nova taxa | "A decisão é humana e fica gravada no banco, com o parecer e a justificativa." | LGPD art. 20 |
| 8 | 5:45 | Aba **Auditoria da carteira**: cartões, faixas e equidade | "Gênero: −0,53 pp; idade 18–25 × 35–44: +5,45 pp. Os dois intervalos não cruzam o zero: indício a investigar, com as ressalvas de proxies e qualidade do dado." | Auditoria de equidade |
| 9 | 7:00 | Fila de revisão com a coluna **Decisão atual**; **Revisar** abre o contrato | "A carteira inteira vira uma fila priorizada pela distância da margem." | Uso operacional |
| 10 | 7:30 | Aba **Registro de decisões** → Exportar | "Trilha completa: quem decidiu, o quê, por quê e se discordou do sistema." | Rastreabilidade |

## 3. Plano B

| Problema na hora | O que fazer |
|---|---|
| Sem internet (Gemini fora) | Seguir: o parecer sai pelo **template de reserva** e o painel mostra isso. Usar como prova do fallback. |
| Modelo não carrega | Usar só **Caso de exemplo** (casos reais já calculados). |
| Banco fora | As decisões ficam na sessão com aviso; mostrar a exportação. |
| Docker não sobe | Passar o **vídeo gravado**. |

## 4. Perguntas prováveis da banca

- **"Por que dados da Estônia?"** Não há base pública brasileira de contratos individuais; o Bondora é substituto do comportamento de crédito, e a análise jurídica é hipotética.
- **"O juro justo é absoluto?"** Não: é relativo à safra (a margem iguala a mediana do justo à do cobrado em cada ano). Mede quem está caro ou barato **perto dos pares da mesma época**.
- **"O backtest confirma a auditoria?"** Resposta combinada com o Samuel (pendência abaixo).
- **"E se a IA inventar um número?"** A conferência por código recusa e entra o template. Na avaliação, 40/40 recomendações certas.
- **"Por que país não está na equidade?"** País é controle de risco (o default varia muito entre EE, ES e FI), não grupo auditado.

## Pendências

- [ ] Ensaio cronometrado com o grupo
- [ ] Gravar o vídeo (resolução 1080p, com áudio)
- [ ] Combinar com o Samuel a resposta sobre o backtest
- [ ] Definir quem fala em cada bloco

## Histórico

| Versão | Data | Mudança |
|---|---|---|
| 1.0 | 10/11/2026 | Primeira versão do roteiro. |
Empty file removed infra/.gitkeep
Empty file.
23 changes: 23 additions & 0 deletions infra/.terraform.lock.hcl

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

27 changes: 27 additions & 0 deletions infra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# infra/ — o ambiente como código (Terraform)

Descreve com Terraform o mesmo ambiente do `docker-compose.yml`: rede, volumes, banco (PostgreSQL + pgvector), API e painel. Usa o provider **Docker** e roda **no próprio computador**: não precisa de conta em nuvem nem gera custo. É a base para levar o projeto a uma nuvem depois, trocando o provider.

O dia a dia continua pelo `.\iniciar.ps1` ou pelo `docker compose`. O Terraform é uma alternativa de implantação, não um passo obrigatório.

## Como usar

Pré-requisitos: [Terraform](https://developer.hashicorp.com/terraform/install) ≥ 1.6 e Docker Desktop ligado.

1. Pare o ambiente do compose (usa as mesmas portas): `docker compose down`
2. Construa a imagem da aplicação (uma vez): `docker compose build api`
3. Na pasta `infra/`:
```
terraform init
$env:TF_VAR_google_api_key = "<chave do Gemini>" # opcional; sem ela o parecer sai pelo template
terraform apply
```
No Linux/macOS, acrescente `-var 'docker_host=unix:///var/run/docker.sock'` (e use `export TF_VAR_google_api_key=...`).
4. Abra os endereços que o `terraform apply` mostra no fim (painel em http://localhost:8501).
5. Para remover tudo: `terraform destroy` (apaga também o volume do banco deste ambiente).

## Observações

- Os containers e volumes têm o prefixo `auditor_tf_`, para não se misturar com os do compose.
- O banco começa vazio, como no compose: o esquema de `db/` roda sozinho na 1ª criação; as cargas e a indexação das normas seguem o README da raiz, apontando para a porta 5432.
- A chave do Gemini nunca vai para arquivo: só pela variável de ambiente `TF_VAR_google_api_key`. Os arquivos de estado (`*.tfstate`) ficam fora do Git, pois podem conter a chave.
Loading
Loading