Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c9abc47
feat(api): overhaul for enterprise performance, resilience and profes…
LAMP-LUCAS May 21, 2026
3699fa9
feat(demo): full-stack overhaul — BI endpoints, CSS @layer, DI archit…
LAMP-LUCAS May 21, 2026
8d67490
feat(sprint-1a): enrich demo UI with badges, BOM comparison, search, …
LAMP-LUCAS May 21, 2026
3dd5283
feat(sprint-1b): maintenance history, ABC grouping, admin UI + timeline
LAMP-LUCAS May 21, 2026
aff912e
fix(bom-cost): remove vertical duplication, add labor/material/equip …
LAMP-LUCAS May 21, 2026
e8ff02d
feat(sprint-2): API professionalization + BI endpoints + demo improve…
LAMP-LUCAS May 22, 2026
f53dd04
fix: minor schema and crud adjustments before traceability sprint
LAMP-LUCAS May 22, 2026
3e8d1e8
docs: add PRD and sprint plans for data traceability & reliability en…
LAMP-LUCAS May 22, 2026
ba57cda
feat: implement traceability & reliability (Sprints 3.1-3.3)
LAMP-LUCAS May 22, 2026
3c9b347
fix: add AutoSINAPI ETL toolkit to tracking (remove from gitignore)
LAMP-LUCAS May 22, 2026
7daa995
feat: add AutoSINAPI ETL traceability changes
LAMP-LUCAS May 22, 2026
94a4886
test: add comprehensive traceability test suite
LAMP-LUCAS May 22, 2026
7d2c9b0
test: fix complete test suite with sandbox isolation
LAMP-LUCAS May 22, 2026
6772ee1
fix: use config table names for sandbox mode
LAMP-LUCAS May 22, 2026
c69dd9a
feat: sandbox ETL population verified with 1.16M records
LAMP-LUCAS May 22, 2026
c3a32d2
fix: install AutoSINAPI locally instead of from GitHub
LAMP-LUCAS May 22, 2026
0657589
Merge branch 'develop' of github.com:LAMP-LUCAS/autoSINAPI_API into d…
LAMP-LUCAS May 22, 2026
e2da391
fix: install AutoSINAPI from local directory in Dockerfile
LAMP-LUCAS May 22, 2026
fe242c3
fix: add SETUPTOOLS_SCM env for AutoSINAPI build
LAMP-LUCAS May 22, 2026
435a3ca
feat: migration 003 - change etl_run_id from UUID to VARCHAR(36)
LAMP-LUCAS May 22, 2026
2d41299
test: fix tests for UUID etl_run_id and TRUNCATE structure tables
LAMP-LUCAS May 22, 2026
5e7ed17
fix(ui/api): resolve 500 cache errors, fix heatmap rendering, and sta…
LAMP-LUCAS May 22, 2026
e6336d2
docs: add technical ROADMAP for future Open Source evolution
LAMP-LUCAS May 23, 2026
4b32dd9
feat(api/ui): refactor Trends to multi-dimension and harden ETL data …
LAMP-LUCAS May 23, 2026
2bba07b
feat: convert AutoSINAPI toolkit into a Git Submodule
LAMP-LUCAS May 24, 2026
70376ff
chore(security): remove hardcoded cloudflare token and update env exa…
LAMP-LUCAS May 24, 2026
ecab944
feat(ci): add Release Drafter and Integration Smoke Test workflows
LAMP-LUCAS May 24, 2026
d317736
chore: update submodule pointer and fix integration tests
LAMP-LUCAS May 25, 2026
620d091
chore: update toolkit submodule with CI/CD fixes
LAMP-LUCAS May 25, 2026
eb173b0
chore: update toolkit submodule with CI stability fix and verified state
LAMP-LUCAS May 25, 2026
7eb0d1a
chore: update toolkit submodule with restored dependencies
LAMP-LUCAS May 25, 2026
2bba3f6
chore: update toolkit submodule with Python 3.8 fix
LAMP-LUCAS May 25, 2026
ce29630
fix(ci): update smoke test to use PipelineETL class name
LAMP-LUCAS May 25, 2026
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
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ KONG_PG_HOST=db
# === Configs da API (FastAPI) ===
# URL de conexão que a API e o Worker usarão para se conectar ao banco de dados.
# Use as mesmas credenciais do POSTGRES_USER e o hostname 'db' do serviço do banco.
DATABASE_URL=postgresql://admin:change-in-production-db-pass@db:5432/sinapi
# === Configs do Cloudflare Tunnel (Opcional) ===
# Token para expor sua API para a internet via túnel.
CLOUDFLARE_TUNNEL_TOKEN=seu-token-aqui
35 changes: 35 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# .github/release-drafter.yml

# Define as categorias com base nos tipos de Conventional Commits
categories:
- title: '🚀 Novas Funcionalidades'
labels:
- 'feature'
- 'feat'
- title: '🐛 Correções de Bugs'
labels:
- 'fix'
- 'bug'
- title: '🔧 Melhorias e Refatorações'
labels:
- 'refactor'
- 'chore'
- title: '📚 Documentação'
labels:
- 'docs'

# Exclui labels que não devem aparecer no changelog
exclude-labels:
- 'skip-changelog'

# O template do corpo da sua release.
# A variável $CHANGES será substituída pela lista categorizada de mudanças.
template: |
## O que há de novo nesta versão?

*Aqui você pode escrever sua copy, explicando o objetivo principal da release.*

$CHANGES

---
**Agradecemos a todos os contribuidores!** 🎉
41 changes: 41 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: CI - API and Integration

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive # CRÍTICO: Puxa o Toolkit

- name: Set up Environment
run: cp .env.example .env

- name: Build Docker Stack
run: docker compose build

- name: Start Services
run: docker compose up -d db redis kong-migrations

- name: Wait for Database
run: |
until docker compose exec db pg_isready -U admin -d sinapi; do
echo "Waiting for database..."
sleep 2
done

- name: Validate Populate-DB (Smoke Test)
run: |
echo "🧪 Executando teste de fumaça do ETL..."
# Rodamos um comando simplificado apenas para verificar se o motor do Toolkit liga corretamente dentro do container da API
docker compose run --rm api python3 -c "from autosinapi.etl_pipeline import PipelineETL; print('✅ Toolkit importado com sucesso na API')"

- name: Cleanup
if: always()
run: docker compose down -v
21 changes: 21 additions & 0 deletions .github/workflows/draft-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# .github/workflows/draft-release.yml

name: Draft a new release

on:
push:
branches:
- develop # Roda toda vez que algo é mesclado em develop

jobs:
update_release_draft:
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
with:
# (Opcional) Publica a release se a tag corresponder,
# mas para o seu caso, vamos deixar o seu 'release.yml' cuidar disso.
# A principal função aqui é apenas ATUALIZAR o rascunho.
publish: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ env.bak
venv.bak
.manage-kong
autosinapi_downloads/
deploy.config

# Docker
.dockerignore
Expand All @@ -70,4 +71,8 @@ docker-compose.override.yml
.vscode/

# Model
AutoSINAPI/
# AutoSINAPI/ <-- Removed: ETL toolkit is part of the project

# Logs
logs/
.pytest_cache/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "AutoSINAPI"]
path = AutoSINAPI
url = https://github.com/LAMP-LUCAS/AutoSINAPI.git
1 change: 1 addition & 0 deletions AutoSINAPI
Submodule AutoSINAPI added at 74ecf2
8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ Utilizamos o padrão [Conventional Commits](https://www.conventionalcommits.org/
- **Python (API e Worker)**: O código segue o padrão **PEP 8**. Usamos `snake_case` para variáveis e funções e `PascalCase` para classes.
- **Infraestrutura (Docker & Kong)**: Nomes de serviços e contêineres devem ser em `snake_case` e descritivos (ex: `celery_worker`, `sinapi_gateway`).

### 4. Trabalhando com o Toolkit (Submódulo)

O core de processamento de dados (`AutoSINAPI/`) é um **submódulo Git** vinculado ao repositório [AutoSINAPI](https://github.com/LAMP-LUCAS/AutoSINAPI).

- **Mudanças no Core:** Devem ser commitadas e enviadas para o repositório do Toolkit.
- **Mudanças na API:** Devem ser commitadas neste repositório.
- **Sincronia:** Se você atualizar o Toolkit, lembre-se de atualizar o ponteiro do submódulo neste repositório com um commit de "update submodule".

---

## Submetendo Alterações
Expand Down
11 changes: 10 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,26 @@ ENV PYTHONUNBUFFERED 1
# Estágio 2: Instalação de dependências
WORKDIR /app
COPY requirements.txt .
# Copy AutoSINAPI toolkit before pip install for local install
COPY ./AutoSINAPI /app/AutoSINAPI
RUN apt-get update && \
apt-get install -y git --no-install-recommends && \
pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir -r requirements.txt && \
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_AUTOSINAPI=0.1.0 pip install --no-cache-dir ./AutoSINAPI && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Estágio 3: Cópia do código da aplicação
COPY ./api /app/api

# Estágio 4: Comando de execução
# Estágio 4: Segurança e Execução
RUN apt-get update && apt-get install -y wget procps --no-install-recommends && \
rm -rf /var/lib/apt/lists/* && \
useradd -m -u 1000 appuser && \
chown -R appuser:appuser /app
USER appuser

# Expõe a porta que o Uvicorn usará
EXPOSE 8000
# Inicia o servidor Uvicorn
Expand Down
26 changes: 19 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@

.PHONY: up down populate-db logs-api logs-kong status
.PHONY: setup up down populate-db logs-api logs-kong status

setup:
@echo "🔧 Inicializando submódulos e ambiente..."
git submodule update --init --recursive
cp .env.example .env

up:
@echo "Iniciando os containers Docker em modo detached..."
docker-compose up --build -d
docker compose up --build -d

down:
@echo "Parando e removendo os containers, redes e volumes..."
docker-compose down -v
docker compose down -v

populate-db:
@echo "Disparando a tarefa de ETL para popular o banco de dados..."
docker-compose exec api python -c "import os; from api.tasks import populate_sinapi_task; db_config = {'host': os.getenv('POSTGRES_HOST', 'db'), 'port': int(os.getenv('POSTGRES_PORT', 5432)), 'database': os.getenv('POSTGRES_DB'), 'user': os.getenv('POSTGRES_USER'), 'password': os.getenv('POSTGRES_PASSWORD')}; sinapi_config = {'year': 2025, 'month': 7}; populate_sinapi_task.delay(db_config, sinapi_config)"
docker compose exec api python -c "import os; from api.tasks import populate_sinapi_task; db_config = {'host': os.getenv('POSTGRES_HOST', 'db'), 'port': int(os.getenv('POSTGRES_PORT', 5432)), 'database': os.getenv('POSTGRES_DB'), 'user': os.getenv('POSTGRES_USER'), 'password': os.getenv('POSTGRES_PASSWORD')}; sinapi_config = {'year': 2025, 'month': 7}; populate_sinapi_task.delay(db_config, sinapi_config)"

logs-api:
@echo "Exibindo logs do container da API..."
docker-compose logs -f api
docker compose logs -f api

logs-kong:
@echo "Exibindo logs do container do Kong..."
docker-compose logs -f kong
docker compose logs -f kong

status:
@echo "Verificando o status dos containers..."
docker-compose ps
docker compose ps

test-env:
@echo "🛠️ Construindo imagem de teste isolada..."
docker build -t autosinapi-test-runner -f tests/Dockerfile.test .
@echo "🧪 Executando testes de build e orquestração em ambiente isolado..."
docker run --rm -v $$(pwd):/app:ro autosinapi-test-runner

37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@ Se você trabalha com orçamentos de obra, sabe o quão repetitivo e frustrante

Tenha sua própria instância da API, com banco de dados e toda a infraestrutura, rodando localmente com apenas 5 passos.

1. **Clone o Repositório**
1. **Clone o Repositório (com Submódulos)**
```bash
git clone https://github.com/LAMP-LUCAS/autoSINAPI_API.git
git clone --recursive https://github.com/LAMP-LUCAS/autoSINAPI_API.git
cd autoSINAPI_API
```
*Caso já tenha clonado sem o `--recursive`, execute:*
```bash
git submodule update --init --recursive
```

2. **Configure o Ambiente**
Copie o arquivo de exemplo `.env.example` para um novo arquivo chamado `.env`. Nenhuma alteração é necessária para começar.
Expand Down Expand Up @@ -98,9 +102,34 @@ Use estes comandos para gerenciar seu ambiente facilmente.
A autoSINAPI API vai além de simples consultas. Oferecemos endpoints de BI que entregam análises valiosas:

- **Estrutura Analítica (BOM):** Exploda uma composição em sua árvore completa de custos.
- **Hora/Homem Total:** Calcule o total de horas de mão de obra em qualquer composição.
- **Otimizador de Custo:** Identifique os 5 maiores vilões de custo em qualquer serviço.
- **Curva ABC:** Envie seu orçamento e descubra quais insumos representam 80% do seu custo.
- **Otimizador de Custo:** Identifique os maiores vilões de custo em qualquer serviço.
- **Série Histórica:** Analise a "inflação" de um insumo ou composição ao longo do tempo.
- **Tendências de Volatilidade:** Analise a inflação setorial agrupada por **Classificação (Insumos)** ou **Grupo (Composições)**, ou monitore a evolução de **Itens Específicos** ao longo de 12 meses.
- **Série Histórica:** Evolução mensal de preços para um item individual.
- **Comparativo Regional:** Compare preços de um mesmo item em diferentes estados do Brasil.

### 🖥️ Frontend Demo

O repositório inclui uma **aplicação web demo** completa em `demo/`. Explore todos os recursos da API visualmente:

```bash
# A demo roda automaticamente no ambiente Docker
# Acesse: https://autosinapi.lamp.local/demo/

# Ou localmente com servidor HTTP simples
cd demo && python3 -m http.server 8080
```

**Recursos do Frontend:**
- **Pesquisa Inteligente:** Busca textual com filtros por estado, data e regime
- **BOM Tree:** Visualização hierárquica em cards ou tabela com scroll infinito
- **Curva ABC:** Gráfico dinâmico (barras + linha) com tabela analítica
- **Comparativo Regional:** Gráfico de barras com destaque de min/max e estatísticas
- **Modal de Detalhes:** Histórico de preços (Chart.js), mão de obra, otimização
- **Totalmente responsivo:** 320px (smartwatch) → 3840px (8K)
- **Dark/Light mode:** com detecção automática do sistema + toggle explícito
- **Acessível:** WCAG 2.1 AA, navegação por teclado, high contrast mode

---

Expand Down
50 changes: 50 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# 🗺️ autoSINAPI ROADMAP — Visão de Evolução Técnica

Este documento define os próximos horizontes técnicos para o projeto **autoSINAPI**, mantendo o compromisso com a filosofia Open Source (GPL-v3) e a capacidade de auto-hospedagem (self-hosting). O objetivo é evoluir de uma ferramenta de consulta para uma plataforma de inteligência em custos de construção.

---

## 🏗️ Fase 2: Automação e Inteligência de Dados

### 1. Zero-Touch ETL (Carga Autônoma)
Atualmente, o processo de população do banco depende de intervenção manual.
- [ ] **Monitoramento Ativo:** Implementar um crawler (Agente Watcher) que monitora o portal de downloads da Caixa Econômica Federal.
- [ ] **Carga Automatizada:** Ao detectar um novo arquivo, disparar o pipeline de extração e inserção via Celery de forma totalmente automática.
- [ ] **Webhooks de Status:** Notificar o administrador via Webhook (Discord/Telegram/Email) sobre o sucesso ou falha da atualização mensal.

### 2. Forecasting com IA (Análise Preditiva)
Aproveitar a massa de dados histórica sanitizada para gerar valor prospectivo.
- [ ] **Integração LLM/Ollama:** Utilizar agentes de IA locais para analisar séries históricas e identificar anomalias ou sazonalidade.
- [ ] **Previsão de Preços:** Implementar modelos de regressão para projetar a variação de preços (Inflação Setorial) para os próximos 3 a 6 meses.
- [ ] **Dashboard de Risco:** Alertas sobre materiais com tendência de alta acentuada, auxiliando na antecipação de compras.

---

## 🔗 Fase 3: Ecossistema e Integrações

### 3. Integração BIM 5D & Plugins
Conectar a API diretamente ao fluxo de projeto.
- [ ] **API Headless para BIM:** Expandir endpoints para facilitar o mapeamento de objetos BIM com códigos SINAPI.
- [ ] **Plugin Revit/AutoCAD:** Protótipo de integração para leitura de custos em tempo real dentro de ferramentas de projeto.
- [ ] **Exportação para ERPs:** Formatos de saída compatíveis com sistemas de gestão de obras open source.

### 4. Custom Personal Databases (Multi-tenancy Técnico)
Permitir que o usuário combine dados oficiais com seus próprios custos.
- [ ] **Composições Próprias:** Criar endpoints `POST` para que usuários cadastrem tabelas de custos locais sem sobrescrever os dados oficiais do SINAPI.
- [ ] **Mix de Preços:** Funcionalidade para calcular orçamentos usando o "SINAPI Oficial" como base, mas substituindo itens específicos por cotações de mercado do usuário.

---

## 🛠️ Fase 4: Excelência Operacional e UX

- [ ] **API v2 (GraphQL):** Implementar suporte a GraphQL para permitir consultas complexas e explosões de BOM em uma única requisição customizada.
- [ ] **Dashboard Pro (Open Source):** Evoluir a interface Demo para um dashboard de gestão completo, com persistência de orçamentos no navegador (LocalStorage/IndexedDB).
- [ ] **Internationalization (i18n):** Preparar a interface para suporte a múltiplos idiomas e moedas, expandindo o uso para outros países que utilizam tabelas de referência similares.

---

**Nota:** Este roteiro é uma declaração de intenções técnica. Com a nova arquitetura modular:
- A **Fase 2 (Inteligência de Dados e ETL)** será desenvolvida prioritariamente no repositório [AutoSINAPI (Toolkit)](https://github.com/LAMP-LUCAS/AutoSINAPI).
- As **Fases 3 e 4 (Integrações e UX)** serão o foco deste repositório da API.

Contribuições da comunidade são bem-vindas via Pull Requests seguindo a licença GPL-v3.
36 changes: 36 additions & 0 deletions alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[alembic]
script_location = alembic
sqlalchemy.url = postgresql://admin:admin@autosinapi_db:5432/sinapi

[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
Loading
Loading