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
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ docs/ decisões de modelagem (DECISOES.md), glossário, BPMN, resultados
genai/ formato JSON, regras, normas, prompts e código do parecer
notebooks/ EDA e etapas do modelo (coortes, variáveis, XGBoost, LGD, margem)
src/api/ API FastAPI
src/app/ painel Streamlit
src/app/ painel Streamlit (main.py = telas, estilo.css = visual, componentes.py = blocos HTML)
src/dados/ cargas do Bondora e das séries de juros
src/modelos/ modelo de risco e juro justo (prever())
modelos_salvos/ pacote do modelo (.joblib, fora do Git)
Expand All @@ -62,11 +62,11 @@ 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`:
**Atalho (Windows):** clique duplo no `iniciar.bat` (ou `.\iniciar.ps1`). Num PC novo basta Docker Desktop, `.env`, o `.joblib` do modelo e os 4 CSVs de custo do dinheiro em `data/raw/` (para a referência do BC): veja [`docs/RODAR_EM_QUALQUER_PC.md`](docs/RODAR_EM_QUALQUER_PC.md). A base do Bondora só é necessária para refazer os dados e o modelo (passos 2 a 5 abaixo).

| 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` | confere portas, `.env` e modelo, sobe o banco, aplica a tabela de decisões, indexa as normas e carrega a referência do BC (se faltarem), 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 |

Expand All @@ -84,7 +84,7 @@ O primeiro build leva alguns minutos (PyTorch); os seguintes reaproveitam o cach

2. **Dados.** Todos os arquivos ficam numa pasta compartilhada do Drive, fora do Git (o repositório é público). Peça o link ao grupo e coloque os arquivos em `data/raw/`, com estes nomes:
- `LoanData_Bondora.csv` (confira o SHA-256 em `DATA.md`)
- `ECB_Euribor_Serie-Mensal-12-Meses_csv.csv` e `ECB_Euribor_Serie-Mensal-3-Meses.csv`
- `ECB_Euribor_Serie-Mensal-12-Meses.csv` (o download do BCE às vezes vem como `..._csv.csv`: os dois nomes funcionam) e `ECB_Euribor_Serie-Mensal-3-Meses.csv`
- `BC-Selic_Acumulada_Mes_Anuzalizada_base252.csv`
- `BC-Meta_Selic_Mensal.csv` (opcional, só conferência)
- `bcdata.sgs.20742.csv` (opcional, referência de mercado do BC)
Expand Down Expand Up @@ -143,7 +143,8 @@ O primeiro build leva alguns minutos (PyTorch); os seguintes reaproveitam o cach
- [`genai/FORMATO_JSON.md`](genai/FORMATO_JSON.md) e [`genai/REGRAS_PARECER.md`](genai/REGRAS_PARECER.md): contrato e regras do parecer.
- [`genai/avaliacao/`](genai/avaliacao/CRITERIOS.md): critérios, os 20 casos de avaliação e os resultados do parecer (prompts v2 a v4), com a revisão humana da v4.
- [`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).
- [`infra/`](infra/README.md): Terraform que cria na Google Cloud uma VM rodando o mesmo Docker Compose (para a demo na nuvem).
- [`docs/RODAR_EM_QUALQUER_PC.md`](docs/RODAR_EM_QUALQUER_PC.md): como rodar em qualquer PC da equipe e a diferença entre Docker e Terraform.
- [`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 All @@ -168,6 +169,6 @@ O primeiro build leva alguns minutos (PyTorch); os seguintes reaproveitam o cach
Cada frente registra aqui como usou assistentes de IA (agentic coding) e como revisou o resultado.

- **Dados:** os scripts de carga, os esquemas SQL e a documentação foram escritos com apoio do Claude e revisados e testados pelo responsável da frente.
- **App e infraestrutura:** a integração da API com o `prever()`, as telas do painel e os testes foram feitos com apoio do Claude, a partir dos protótipos do grupo e dos contratos (`FORMATO_JSON.md`, `REGRAS_PARECER.md`). A responsável revisou o código e conferiu o resultado com testes automáticos e rodando as telas.
- **App e infraestrutura:** a integração da API com o `prever()`, as telas do painel e os testes foram feitos com apoio do Claude, a partir dos protótipos do grupo e dos contratos (`FORMATO_JSON.md`, `REGRAS_PARECER.md`). A responsável revisou o código e conferiu o resultado com testes automáticos e rodando as telas. O formulário com etapas travadas, a separação do visual em `estilo.css` e os scripts `iniciar` seguiram o mesmo processo.
- **Modelo:** a completar pela frente.
- **GenAI:** o código do parecer, os prompts e os documentos da frente foram escritos com apoio do Claude, guiado pelos guias da frente em `skills/regras_negocio/` ([`normas_rag`](skills/regras_negocio/normas_rag/SKILL.md), [`parecer_genai`](skills/regras_negocio/parecer_genai/SKILL.md) e [`avaliacao_parecer`](skills/regras_negocio/avaliacao_parecer/SKILL.md)) e pelos contratos (`FORMATO_JSON.md`, `REGRAS_PARECER.md`). As propostas maiores (template, cadeia em LangChain, prompts v3 e v4) também passaram pela revisão de uma segunda IA. A responsável leu cada mudança antes de aplicá-la e conferiu o resultado com os testes automáticos (`tests/genai/`), a avaliação dos 20 casos e a revisão humana dos pareceres (`genai/avaliacao/`).
69 changes: 69 additions & 0 deletions docs/RODAR_EM_QUALQUER_PC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Rodar o Auditor em qualquer PC da equipe

## Docker e Terraform: para que serve cada um

| | Docker Compose (`iniciar.bat`) | Terraform (`infra/`) |
| --- | --- | --- |
| O que faz | sobe banco, API e painel **no seu PC** | cria **uma máquina na Google Cloud** que roda o mesmo Docker Compose |
| Quando usar | no dia a dia, nos testes e como plano B da demo | para mostrar o sistema na nuvem e a "infraestrutura como código" |
| Custo | nenhum | gasta o crédito grátis da Google enquanto a máquina existir |
| Guia | este arquivo | [`infra/README.md`](../infra/README.md) |

**Quem roda a aplicação é sempre o Docker.** O `docker-compose.yml` descreve os 3 containers.
O Terraform não substitui o Docker: ele cria o *computador* (rede, IP, firewall e VM) onde o Docker vai rodar.
Em uma frase: **"Docker empacota a aplicação; Terraform cria a infraestrutura onde ela roda."**

## 1. Uma vez por PC

| O quê | De onde |
| --- | --- |
| Docker Desktop | docker.com → *Download Docker Desktop* (Windows: aceite o WSL 2). Abra e espere ficar verde. |
| Git | git-scm.com |
| Projeto | `git clone https://github.com/yaMimis/Auditor-Project.git` |
| `.env` | peça à Yasmin (tem a `GOOGLE_API_KEY` e a `CLIENTE_ID_SAL`). Nunca vai para o GitHub. |
| `modelos_salvos\pacote_prever_v1.joblib` | peça ao Samuel (Drive) |
| 4 CSVs de custo do dinheiro em `data\raw\` | peça ao Marcos (Drive), nomes abaixo |

Os 4 CSVs (são pequenos, séries mensais do Banco Central e do Banco Central Europeu):

- `ECB_Euribor_Serie-Mensal-12-Meses_csv.csv` (ou sem o `_csv`)
- `ECB_Euribor_Serie-Mensal-3-Meses.csv`
- `BC-Selic_Acumulada_Mes_Anuzalizada_base252.csv`
- `bcdata_sgs_20742.csv` (ou `bcdata.sgs.20742.csv`): a taxa média do crédito pessoal, que vira a "referência de mercado" no parecer

Na primeira vez, o `iniciar` carrega esses arquivos no banco sozinho. Os mesmos 4 arquivos vão para a nuvem (passo 14 do `infra/README.md`).

Os arquivos da aba "Auditoria da carteira" (`docs\resultados\`, gerados pelo Samuel) já vêm com o `git clone`.

A base grande do Bondora (`LoanData`) **não** é necessária para rodar o sistema. Ela só serve para refazer
os dados e o modelo (passos 2 a 5 do README).

## 2. Todo dia

**Clique duplo no `iniciar.bat`** (ou `.\iniciar.ps1` no PowerShell). Ele:

1. confere se o Docker está ligado e se as portas 5432, 8000 e 8501 estão livres;
2. confere o `.env` e o modelo;
3. sobe o banco e aplica a tabela de decisões;
4. constrói a imagem só se ela não existir;
5. indexa as normas e carrega a referência do BC, se faltarem;
6. sobe API e painel e abre http://localhost:8501.

| Situação | Comando |
| --- | --- |
| Subir | `iniciar.bat` ou `.\iniciar.ps1` |
| Veio código novo no `git pull` | `.\iniciar.ps1 -Build` |
| Desligar (os dados ficam) | `.\iniciar.ps1 -Parar` |
| Ver o que deu errado | `docker compose logs api --tail 40` |

## 3. Problemas comuns

| Mensagem | O que fazer |
| --- | --- |
| "O Docker não está rodando" | Abra o Docker Desktop e espere ficar verde |
| "A porta X está com o container Y" | `docker stop Y` (o script mostra o comando) e rode de novo |
| "A porta X está ocupada pelo programa Y" | Feche o programa (o script mostra o comando) |
| "Sem a referência de mercado do BC" | Coloque os 4 CSVs em `data\raw\` e rode de novo |
| "não está assinado" / ExecutionPolicy | Use o `iniciar.bat`, ou antes: `Set-ExecutionPolicy Bypass -Scope Process` |
| "Falta modelos_salvos\...joblib" | Peça o arquivo ao Samuel; até lá, use "Caso de exemplo" |
| API demora na 1ª vez | Normal: ela baixa o modelo de busca nas normas (~0,5 GB) uma única vez |
4 changes: 2 additions & 2 deletions infra/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ output "comando_esperar_vm" {
}

output "comando_enviar_arquivos" {
description = "Envia o modelo e os CSVs de custo do dinheiro, que não estão no Git"
value = "scp -i ${local.chave} modelos_salvos/pacote_prever_v1.joblib data/raw/ECB_Euribor_Serie-Mensal-12-Meses_csv.csv data/raw/ECB_Euribor_Serie-Mensal-3-Meses.csv data/raw/BC-Selic_Acumulada_Mes_Anuzalizada_base252.csv data/raw/bcdata_sgs_20742.csv ${var.usuario}@${local.ip}:~/envio/"
description = "Envia o modelo e os CSVs de custo do dinheiro, que não estão no Git (nomes como estão no Drive do grupo)"
value = "scp -i ${local.chave} modelos_salvos/pacote_prever_v1.joblib data/raw/ECB_Euribor_Serie-Mensal-12-Meses.csv data/raw/ECB_Euribor_Serie-Mensal-3-Meses.csv data/raw/BC-Selic_Acumulada_Mes_Anuzalizada_base252.csv data/raw/bcdata.sgs.20742.csv ${var.usuario}@${local.ip}:~/envio/"
}

output "comando_completar" {
Expand Down
6 changes: 6 additions & 0 deletions iniciar.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@echo off
rem Clique duplo para subir o Auditor de Preco Justo (banco, API e painel).
rem Mesmo efeito de .\iniciar.ps1; repassa opcoes, ex.: iniciar.bat -Build
cd /d "%~dp0"
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0iniciar.ps1" %*
pause
41 changes: 35 additions & 6 deletions iniciar.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# .\iniciar.ps1 -Build reconstroi a imagem antes (mudou codigo ou requirements)
# .\iniciar.ps1 -Parar para tudo (os dados do banco continuam no volume)
# .\iniciar.ps1 -SemNavegador nao abre o navegador no final
# Ou de clique duplo no iniciar.bat (mesmo efeito, sem mexer na ExecutionPolicy).
# Se o Windows bloquear o script, rode antes, na mesma janela:
# Set-ExecutionPolicy Bypass -Scope Process
#
Expand Down Expand Up @@ -52,6 +53,21 @@ if ($Parar) {
exit 0
}

# Portas livres? (5432 banco, 8000 API, 8501 painel). Outro container ou programa nelas impede a subida.
$nossos = @("auditor_postgres", "auditor_api", "auditor_streamlit")
$programas_docker = @("com.docker.backend", "wslrelay", "vpnkit", "com.docker.proxy", "dockerd", "docker")
foreach ($porta in 5432, 8000, 8501) {
$outro = docker ps --filter "publish=$porta" --format "{{.Names}}" | Where-Object { $nossos -notcontains $_ }
if ($outro) { Parar "A porta $porta esta com o container '$outro'. Pare com: docker stop $outro e rode de novo." }
$con = Get-NetTCPConnection -LocalPort $porta -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1
if ($con) {
$proc = Get-Process -Id $con.OwningProcess -ErrorAction SilentlyContinue
if ($proc -and ($programas_docker -notcontains $proc.ProcessName)) {
Parar "A porta $porta esta ocupada pelo programa '$($proc.ProcessName)'. Feche-o com: Stop-Process -Id $($proc.Id) e rode de novo."
}
}
}

# 1. .env (fica fora do Git): cria um modelo se nao existir, sem sobrescrever o seu
Passo "1/6 Conferindo o .env e o modelo"
if (-not (Test-Path ".env")) {
Expand Down Expand Up @@ -93,10 +109,6 @@ docker exec auditor_postgres psql -q -U postgres -d auditor_db -v ON_ERROR_STOP=
if ($LASTEXITCODE -ne 0) { Parar "Erro ao aplicar db\05_decisoes_analista.sql. Rode o comando a mao para ver a mensagem." }
Ok "tabela decisao_analista"

$contratos = docker exec auditor_postgres psql -tA -U postgres -d auditor_db -c "SELECT count(*) FROM emprestimo" 2>$null
if ("$contratos".Trim() -eq "0") {
Aviso "O banco esta sem os contratos (cargas do README, passo 5). O painel funciona, mas sem a referencia de mercado do BC."
}

# 4. Imagem: so constroi se nao existir ou se pedirem -Build
Passo "4/6 Imagem da aplicacao"
Expand All @@ -110,8 +122,8 @@ if ($Build -or $LASTEXITCODE -ne 0) {
Ok "imagem ja existe (use -Build se mudou codigo ou requirements)"
}

# 5. Normas do parecer no pgvector (dentro do container: nao precisa de Python local)
Passo "5/6 Normas do parecer"
# 5. Normas do parecer no pgvector e referencia de mercado do BC (dentro do container: sem Python local)
Passo "5/6 Normas do parecer e referencia do BC"
$trechos = docker exec auditor_postgres psql -tA -U postgres -d auditor_db -c "SELECT count(*) FROM trechos_normas" 2>$null
if ("$trechos".Trim() -match "^[1-9]") {
Ok "normas ja indexadas ($("$trechos".Trim()) trechos)"
Expand All @@ -121,6 +133,23 @@ if ("$trechos".Trim() -match "^[1-9]") {
else { Ok "normas indexadas" }
}

# Referencia do BC: series mensais de 4 CSVs pequenos em data\raw (a base do Bondora nao e necessaria).
# Mesma carga que o completar.sh faz na VM da nuvem (infra/cloud-init.yaml).
$meses_bc = docker exec auditor_postgres psql -tA -U postgres -d auditor_db -c "SELECT count(*) FROM bc_credito_pessoal_mensal" 2>$null
if ("$meses_bc".Trim() -match "^[1-9]") {
Ok "referencia do BC ja carregada ($("$meses_bc".Trim()) meses)"
} elseif (-not ((Test-Path "data\raw\bcdata.sgs.20742.csv") -or (Test-Path "data\raw\bcdata_sgs_20742.csv"))) {
Aviso "Sem a referencia de mercado do BC: falta data\raw\bcdata.sgs.20742.csv (baixe em https://api.bcb.gov.br/dados/serie/bcdata.sgs.20742/dados?formato=csv) e rode de novo."
} elseif ((Test-Path "data\raw\ECB_Euribor_Serie-Mensal-3-Meses.csv") -and
(Test-Path "data\raw\BC-Selic_Acumulada_Mes_Anuzalizada_base252.csv")) {
$pasta_raw = (Resolve-Path "data\raw").Path
docker compose run --rm --no-deps -v "${pasta_raw}:/app/data/raw:ro" api python src/dados/carga_macro.py --ddl db/02_schema_macro.sql
if ($LASTEXITCODE -ne 0) { Aviso "A carga das series do BC falhou (veja a mensagem acima). O painel funciona sem a referencia de mercado." }
else { Ok "Euribor, Selic e taxa do BC carregadas" }
} else {
Aviso "Sem a referencia de mercado do BC. Coloque em data\raw os CSVs da Euribor (12 e 3 meses) e da Selic (peca ao Marcos) e rode de novo."
}

# 6. API e painel em segundo plano; espera a API ficar saudavel
Passo "6/6 Subindo a API e o painel"
docker compose up -d api streamlit
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ requests>=2.31.0
python-dotenv

# Painel
streamlit>=1.37.0
streamlit>=1.44.0 # st.container(key=...) e ícones nos botões (etapas do formulário)

# Banco de Dados
sqlalchemy>=2.0.0
Expand Down
16 changes: 13 additions & 3 deletions skills/regras_negocio/painel/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Use para construir ou alterar o painel Streamlit do Auditor de Pre

# Painel do analista (Streamlit)

> Leia antes: `regras_negocio/governanca`, `regras_negocio/contratos_dados`, `regras_negocio/api`. Dono: Yasmin. Código: `src/app/main.py` (tela), `src/app/componentes.py` (formatação e HTML, sem Streamlit), `src/app/carteira.py` (leitura e resumo do lote); testes `tests/app/`.
> Leia antes: `regras_negocio/governanca`, `regras_negocio/contratos_dados`, `regras_negocio/api`. Dono: Yasmin. Código: `src/app/main.py` (telas), `src/app/estilo.css` (todo o CSS; o `main.py` só injeta), `src/app/componentes.py` (formatação e HTML, sem Streamlit), `src/app/carteira.py` (leitura e resumo do lote); testes `tests/app/`.

## Objetivo

Expand All @@ -28,11 +28,13 @@ Dar ao analista, em uma tela, **o risco, o preço, o porquê e o parecer** de ca
### Aba 1 — Revisão de contrato

- Origem: **Novo contrato (formulário)** ou **Caso de exemplo**: os 8 casos reais de `docs/casos_de_teste.json` (reserva: `docs/exemplos_prever.json`), abertos com parecer via `/parecer`.
- **Formulário em 3 etapas**, com "Confirmo que revisei" por etapa, barra de progresso REVISADO/PENDENTE e resumo do pedido:
- **Formulário em 3 etapas travadas**, com "Confirmo que revisei" por etapa, barra de progresso REVISADO/PENDENTE e resumo do pedido:
- uma etapa só abre com todas as anteriores revisadas (🔒 e botão desabilitado); voltar é sempre permitido; "Avançar para …" só com a caixa marcada;
- mudar um campo depois de revisado **desmarca** a revisão daquela etapa; desmarcar uma etapa anterior leva de volta à primeira pendente;
- 01 Dados pessoais: idade, gênero (0 Masculino · 1 Feminino · 2 Não informado; só auditoria), país (EE/FI/ES), renda mensal (€)
- 02 Empréstimo: ID, valor (€), juro cobrado (% a.a.), prazo (3–60 meses), data de concessão (01/01/2009 até hoje; padrão hoje)
- 03 Dívidas & histórico: total de dívidas (€); os demais campos seguem "sem informação"
- Botão "⚖️ EXECUTAR AUDITORIA DE PREÇO".
- Botão "⚖️ EXECUTAR AUDITORIA DE PREÇO" **desabilitado até as 3 caixas**, com o aviso "Falta revisar: …"; o código também confere antes de chamar a API.
- **Resultado:**
- cabeçalho: contrato, país, data, valor, prazo, etiqueta da situação, chips ("Custo do dinheiro: Euribor da época", "Parecer: análise hipotética pela lei brasileira", versão do modelo, "Caso real da base", "Exemplo ilustrativo" ou "Aberto da carteira");
- 4 cartões: risco de inadimplência (PD, IC 95% quando houver, faixa) · juro cobrado · juro justo com margem · situação do preço (cor da situação, pp além da margem);
Expand Down Expand Up @@ -67,6 +69,9 @@ Cartões (decisões, diferentes da recomendação, encaminhadas ao compliance),
| Acima do justo | `#e8a462` · Abaixo `#c3a6f0` · Dentro `#8cc7a1` · Revisão manual `#9aa5b5` |
| Aumenta / reduz risco | `#d9825b` / `#7fa7d9` |
| Fontes | títulos Playfair Display; texto DM Sans |
| Abas principais (Revisão · Carteira · Registro) | cartões de 104 px, gradiente escuro; aba ativa com gradiente dourado `#c89a58 → #e4bd7d` e texto `#171315` |
| Etapas do formulário (Dados pessoais · Empréstimo · Dívidas) | abas de texto pequenas, alinhadas à esquerda, sem caixa: cinza `#9aa5b5`, hover só muda a cor, ativa dourada `#e4bd7d` com traço de 2 px `#c89a58`; travada com opacidade 38% |
| Ícones | nada de emoji: ícones de linha brancos (`componentes.icone()`, SVG) no HTML e Material (`icon=":material/...:"`) nos botões; etapa revisada `check_circle`, travada `lock` |

Tema do Streamlit (`.streamlit/config.toml`): `base="dark"`, `primaryColor="#D4AD70"`, `backgroundColor="#080D16"`, `secondaryBackgroundColor="#101A2A"`, `textColor="#F1F0EB"`, `headless=true`, `gatherUsageStats=false`.

Expand All @@ -81,3 +86,8 @@ Tema do Streamlit (`.streamlit/config.toml`): `base="dark"`, `primaryColor="#D4A
- **[A CONFIRMAR] (Marcos)** rótulos dos códigos de escolaridade, moradia e verificação (`CODIGOS` em `componentes.py`, tirados do dicionário do Bondora).
- **[PENDENTE] (Yasmin)** mostrar "a.a. nominal" ao lado dos juros.
- **[PENDENTE] (depende de outras frentes)** `juro_pares_mediana` como referência ao lado do juro justo ("Mediana dos pares: X%", oculto quando `null`; até 09/11); `contexto_mercado` do BC no parecer; decisões gravadas no banco e marcação "já decidido" na fila; dados reais da carteira (08/11 e 09/11).

## Estado em 10/11/2026

- **[PRONTO]** emojis trocados por ícones brancos; CSS separado em `estilo.css`; abas principais como cartões e etapas como abas de texto pequenas; etapas travadas e execução só com as 3 confirmações.
- **[DECIDIDO]** sem tela de login: o sistema roda no PC de cada pessoa e o nome do analista é digitado (obrigatório para decidir). Login só faria sentido com o site publicado.
Loading
Loading