chore: cleanup git — remove IDE files, LESSONS_LEARNED, update README
- Removed from git: .idea/, .DS_Store, LESSONS_LEARNED.md, frontend-react/README.md - Updated .gitignore: added LESSONS_LEARNED.md, dist/, .vscode/, **/.DS_Store - Removed legacy frontend/ directory from disk - README: updated thread pool 16→10, Terraform 1.7.5→1.14.7, i18n 625→700+ keys - README: added RAG optimizations (single connection, smart skip, follow-up enrichment, source hierarchy) - README: added embedding features (auto-map, per-section, CIS tagging, progress bar, background persistence) - README: updated Dockerfile description (Chromium), stores description (app state persistence)
This commit is contained in:
10
.idea/.gitignore
generated
vendored
10
.idea/.gitignore
generated
vendored
@@ -1,10 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Ignored default folder with query files
|
|
||||||
/queries/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
6
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<settings>
|
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
|
||||||
<version value="1.0" />
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
||||||
12
.idea/material_theme_project_new.xml
generated
12
.idea/material_theme_project_new.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="MaterialThemeProjectNewConfig">
|
|
||||||
<option name="metadata">
|
|
||||||
<MTProjectMetadataState>
|
|
||||||
<option name="migrated" value="true" />
|
|
||||||
<option name="pristineConfig" value="false" />
|
|
||||||
<option name="userId" value="-78ab09c0:19707a56f58:-7ffe" />
|
|
||||||
</MTProjectMetadataState>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
7
.idea/misc.xml
generated
7
.idea/misc.xml
generated
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Black">
|
|
||||||
<option name="sdkName" value="Python 3.10 (oci-cis-agent)" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (oci-cis-agent)" project-jdk-type="Python SDK" />
|
|
||||||
</project>
|
|
||||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/oci-cis-agent.iml" filepath="$PROJECT_DIR$/.idea/oci-cis-agent.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
10
.idea/oci-cis-agent.iml
generated
10
.idea/oci-cis-agent.iml
generated
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="PYTHON_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="jdk" jdkName="Python 3.10 (oci-cis-agent)" jdkType="Python SDK" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,378 +0,0 @@
|
|||||||
# OCI CIS Agent — Lições Aprendidas (Erros & Acertos)
|
|
||||||
|
|
||||||
> Documento de referência para uso como prompt em projetos futuros.
|
|
||||||
> Projeto: FastAPI + React 19 SPA + OCI GenAI + MCP + Terraform Agent
|
|
||||||
> Evolução: v1.0 → v2.8 (~4 meses de desenvolvimento iterativo)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Arquitetura & Decisões Fundamentais
|
|
||||||
|
|
||||||
### ACERTOS
|
|
||||||
|
|
||||||
#### 1.1 Chat Assíncrono desde o início (v2.0)
|
|
||||||
- **Padrão**: POST `/api/chat` retorna imediatamente com `message_id`; frontend faz polling em `/api/chat/{mid}/status`
|
|
||||||
- **Resultado**: Eliminou 504 timeouts em respostas lentas do GenAI
|
|
||||||
- **Regra**: Para qualquer endpoint que dependa de LLM, adote async-first desde o dia 1. Polling a cada 2s é aceitável
|
|
||||||
|
|
||||||
#### 1.2 SQLite como banco principal para monolito
|
|
||||||
- **Decisão**: SQLite com WAL mode + busy_timeout=30s para estado compartilhado
|
|
||||||
- **Resultado**: Rápido (<5ms leitura), ACID, zero containers extras, funciona até ~12 chats simultâneos
|
|
||||||
- **Regra**: Use SQLite para monolitos. Migre para banco dedicado quando atingir ~50 requests concorrentes
|
|
||||||
|
|
||||||
#### 1.3 Multi-worker com estado no banco (não em memória)
|
|
||||||
- **Problema**: 8 workers uvicorn = 8 processos separados. Dicts em memória NÃO são compartilhados
|
|
||||||
- **Solução**: Todo estado compartilhado vai para SQLite (sessões, cache MCP, workspaces Terraform)
|
|
||||||
- **Regra**: Ao escalar workers, assuma que memória é local. Banco de dados é a fonte de verdade
|
|
||||||
|
|
||||||
#### 1.4 Cache agressivo para APIs externas
|
|
||||||
- **Padrão**: MCP sessions cacheadas por 2h; Terraform resource docs cacheados no SQLite
|
|
||||||
- **Resultado**: Scans OCI caíram de ~3min para <10s no cache hit
|
|
||||||
- **Regra**: Cache tudo que vem de API externa. TTL de 2h é prático para OCI; ajuste por serviço
|
|
||||||
|
|
||||||
#### 1.5 System prompts compactos para geração de código
|
|
||||||
- **Evolução**: Prompt do Terraform foi de ~200 linhas → ~30 linhas (~2.3K chars)
|
|
||||||
- **Descoberta**: GPT-5.2/o3 via OCI funcionam melhor com regras concisas que com exemplos verbosos
|
|
||||||
- **Regra**: Para agentes de código, priorize **regras > exemplos**. Alvo: <3K chars no system prompt. Use exemplos apenas para casos ambíguos
|
|
||||||
|
|
||||||
#### 1.6 Validação de tipos com fuzzy matching
|
|
||||||
- **Implementação**: `terraform providers schema -json` → SQLite (~937 tipos OCI) + `difflib.get_close_matches`
|
|
||||||
- **Resultado**: Modelo gera `oci_core_vcn_x` → sistema sugere `oci_core_vcn`
|
|
||||||
- **Regra**: Para geração de código, valide contra catálogo estático. Gere na startup do container, cache no banco
|
|
||||||
|
|
||||||
#### 1.7 Geração de referência no startup (não no build)
|
|
||||||
- **Problema**: Arquivo gerado no build → perdido quando volume Docker sobrescreve o diretório
|
|
||||||
- **Solução**: Gerar no entrypoint do container, salvar em `/data/`
|
|
||||||
- **Regra**: Docker volume mounts sobrescrevem artefatos de build. Dados dinâmicos devem ser gerados em runtime
|
|
||||||
|
|
||||||
#### 1.8 RAG separado por contexto de agente
|
|
||||||
- **Problema**: Terraform Agent tentava buscar RAG no ADB (banco vetorial externo) que ficava parado, travando o chat
|
|
||||||
- **Solução**: Terraform usa apenas SQLite local (resource reference + docs oficiais). ADB só para Chat Agent
|
|
||||||
- **Regra**: Cada agente deve ter suas fontes de dados bem definidas. Não compartilhe pipelines de RAG entre agentes com necessidades diferentes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ERROS
|
|
||||||
|
|
||||||
#### 1.9 Provider region hardcoded no Terraform
|
|
||||||
- **Bug**: `provider.tf` era gerado com `region = "us-ashburn-1"` (string fixa da OCI config) em vez de `var.region`
|
|
||||||
- **Impacto**: Recursos provisionados em Ashburn ao invés de Madrid → erro de quota → recursos órfãos para limpar manualmente
|
|
||||||
- **Correção**: Provider sempre usa `var.region`. Se modelo não declara `variable "region"`, plan é **bloqueado** com erro explicativo
|
|
||||||
- **Regra**: NUNCA hardcode valores de infraestrutura. Sempre use variáveis. Implemente guardrails que bloqueiem antes de provisionar
|
|
||||||
|
|
||||||
#### 1.10 Estado travado após restart do container
|
|
||||||
- **Bug**: Workspace com status `planning`/`applying` fica preso se container reinicia — nenhum botão aparece no frontend
|
|
||||||
- **Correção**: Frontend mostra botão Plan para todos os estados (incluindo os "travados")
|
|
||||||
- **Regra**: Sempre considere o cenário de restart. Status intermediários devem ter recovery path
|
|
||||||
|
|
||||||
#### 1.11 HCL single-line blocks inválidos
|
|
||||||
- **Bug**: Modelos geram `variable "x" { type = string, default = "y" }` (inválido em HCL)
|
|
||||||
- **Correção**: Regex auto-fix em frontend E backend para expandir para multi-line
|
|
||||||
- **Regra**: Para geração de código, implemente auto-correção de sintaxe em múltiplas camadas
|
|
||||||
|
|
||||||
#### 1.12 Modelo descarta arquivos na correção
|
|
||||||
- **Bug**: Ao corrigir erros, modelo retorna APENAS arquivos corrigidos, descartando os não alterados
|
|
||||||
- **Correção**: Merge-based updates: arquivos existentes com mesmo nome → substituídos; sem match → preservados
|
|
||||||
- **Regra**: Workflows de correção AI precisam de semântica de merge, não de substituição
|
|
||||||
|
|
||||||
#### 1.13 sqlite3.Row não suporta .get()
|
|
||||||
- **Bug**: `row.get("column")` crasha porque sqlite3.Row não tem método `.get()`
|
|
||||||
- **Correção**: Usar `try/except` com acesso direto `row["column"]` ou converter para `dict(row)`
|
|
||||||
- **Regra**: Conheça as limitações do seu ORM/driver. sqlite3.Row é dict-like mas não é dict
|
|
||||||
|
|
||||||
#### 1.14 reasoning_effort case-sensitive no OCI SDK
|
|
||||||
- **Bug**: OCI SDK requer `"HIGH"` (uppercase), não `"high"`
|
|
||||||
- **Regra**: Sempre consulte a documentação do SDK para formatos exatos. Normalize inputs com `.upper()` antes de enviar
|
|
||||||
|
|
||||||
#### 1.15 Index.html monolítico
|
|
||||||
- **Status**: ~2820 linhas de vanilla JS — manutenção cada vez mais difícil
|
|
||||||
- **Limite prático**: ~2000 linhas para SPA vanilla. Acima disso, framework de componentes se paga
|
|
||||||
- **Plano**: Migração para React (Vite + TypeScript), mantendo FastAPI backend
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Pipeline de Geração de Código (Terraform)
|
|
||||||
|
|
||||||
### ACERTO: Pipeline 3 camadas
|
|
||||||
|
|
||||||
1. **Frontend** (`_splitTfMonolith`): Detecta arquivos monolíticos (≤2 blocos + >2000 chars) e divide
|
|
||||||
2. **Backend** (`_split_tf_monolith`): Validação Python, split por categoria (networking.tf, compute.tf)
|
|
||||||
3. **Deduplicação** (`_write_tf_files`): Remove declarações duplicadas de recursos
|
|
||||||
|
|
||||||
**Regra**: Para geração de código, implemente validação + auto-correção em camadas (client + server). Belt-and-suspenders funciona.
|
|
||||||
|
|
||||||
### ACERTO: Checklist de validação no prompt
|
|
||||||
|
|
||||||
14 pontos obrigatórios no system prompt:
|
|
||||||
- Cross-references entre recursos
|
|
||||||
- Validação de CIDRs
|
|
||||||
- Security lists + route tables
|
|
||||||
- DRG attachments + RPC peering
|
|
||||||
- Sintaxe HCL (blocos multi-line)
|
|
||||||
- Tipos de recursos válidos
|
|
||||||
- Declaração de variáveis
|
|
||||||
|
|
||||||
**Regra**: Checklists no prompt funcionam melhor que exemplos para evitar erros comuns
|
|
||||||
|
|
||||||
### ACERTO: Auto-inject de terraform.tfvars
|
|
||||||
|
|
||||||
- Scan de variáveis declaradas nos `.tf` files
|
|
||||||
- Map automático: `tenancy_ocid`, `user_ocid`, `fingerprint`, `compartment_id`, `ssh_public_key`
|
|
||||||
- Valores vêm da OCI config ativa (criptografada no banco)
|
|
||||||
|
|
||||||
**Regra**: Automatize tudo que pode ser derivado de configuração existente. Menos inputs manuais = menos erros
|
|
||||||
|
|
||||||
### ERRO: Timeout de polling insuficiente
|
|
||||||
|
|
||||||
- **Bug**: Frontend tinha 1h de timeout para polling, mas operações grandes (multi-region) podiam levar mais
|
|
||||||
- **Regra**: Timeout de polling deve ser generoso. 1h para plan, 2h para apply. Melhor sobrar que faltar
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Integração com OCI
|
|
||||||
|
|
||||||
### ACERTOS
|
|
||||||
|
|
||||||
- **OCID-based model resolution**: Catálogo mapeia model IDs para OCIDs por região
|
|
||||||
- **16 regiões OCI**: Endpoints auto-gerados (`https://inference.generativeai.{region}.oci.oraclecloud.com`)
|
|
||||||
- **Wallet auto-parse**: Upload de .zip → extrai password + DSN automaticamente
|
|
||||||
- **GenAI config auto-resolve**: Detecta config a partir de credenciais OCI (menos setup manual)
|
|
||||||
|
|
||||||
### ERROS
|
|
||||||
|
|
||||||
- **VCN deletion em cascata**: VCNs não podem ser deletadas com dependências (subnets, route tables, security lists, DRG attachments, RPCs). Ordem: RPCs → DRG Attachments → Subnets → SGWs → non-default RTs/SLs → VCNs → DRGs
|
|
||||||
- **Default resources não deletáveis**: Route tables e security lists default são tied ao lifecycle da VCN — não tente deletar independentemente
|
|
||||||
- **SSH key ≠ API key**: SSH public key (para compute) é diferente da private key OCI API. Armazene separadamente na config
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Frontend / UX
|
|
||||||
|
|
||||||
### ACERTOS
|
|
||||||
|
|
||||||
- **SVG icons (Lucide)**: Consistência cross-OS, themeable via CSS, zero CDN
|
|
||||||
- **CSS variables para tema**: Dark/light mode com toggle simples (`:root { --bg: ... }`)
|
|
||||||
- **Oracle Dark Premium**: Palette documentada (`#0D0F12` background, `#C74634` accent)
|
|
||||||
- **Chart.js para dashboards**: Leve, sem dependência de React, gauge + donut + bar
|
|
||||||
- **Confirmation modals**: Digitar "DESTROY"/"ROLLBACK" para ações destrutivas
|
|
||||||
|
|
||||||
### ERROS
|
|
||||||
|
|
||||||
- **Emojis inconsistentes**: ✅ ❌ ⚠️ renderizam diferente em cada OS → SVG resolveu
|
|
||||||
- **Layout complexo sem framework**: Resize handles, split panels, tabs — tudo manual em vanilla JS. Funciona mas é frágil
|
|
||||||
- **Scroll references quebradas**: Renomear CSS classes quebra scroll automático silenciosamente
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Operacional & Deploy
|
|
||||||
|
|
||||||
### Padrão de Deploy
|
|
||||||
```bash
|
|
||||||
docker compose up -d --build backend && docker compose restart frontend
|
|
||||||
```
|
|
||||||
- Backend: rebuild necessário (código Python)
|
|
||||||
- Frontend: restart necessário (nginx serve index.html via bind mount, mas precisa reload)
|
|
||||||
|
|
||||||
### RCP (Shortcut do usuário)
|
|
||||||
- **R**EADME: atualizar changelog
|
|
||||||
- **C**ommit: mensagem descritiva
|
|
||||||
- **P**ush: enviar para remote
|
|
||||||
|
|
||||||
### Versionamento
|
|
||||||
- Bump de versão no badge do README + entrada no changelog
|
|
||||||
- Versão semântica simplificada (v2.1, v2.2, etc.)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Regras para AI Coding Assistant
|
|
||||||
|
|
||||||
### Fazer
|
|
||||||
- Ler arquivo antes de editar (entender contexto)
|
|
||||||
- Preferir editar existente vs criar novo (evitar file bloat)
|
|
||||||
- Deploy combo sempre (backend build + frontend restart)
|
|
||||||
- Testar cenários de restart/recovery
|
|
||||||
- Validar inputs em múltiplas camadas
|
|
||||||
|
|
||||||
### Não fazer
|
|
||||||
- Incluir atribuição AI em commits/código
|
|
||||||
- Hardcode valores de infraestrutura
|
|
||||||
- Compartilhar pipeline de RAG entre agentes diferentes
|
|
||||||
- Injetar variáveis automaticamente quando o modelo esquece (forçar correção)
|
|
||||||
- Usar `.get()` em sqlite3.Row
|
|
||||||
- Confiar que status intermediários vão se resolver sozinhos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Stack & Trade-offs
|
|
||||||
|
|
||||||
| Componente | Escolha | Por quê | Limite |
|
|
||||||
|------------|---------|---------|--------|
|
|
||||||
| Backend | FastAPI | Python-first (OCI SDK), async nativo | Mais lento que Go/Rust |
|
|
||||||
| Frontend | Vanilla JS → React | Zero build step inicialmente | ~2000 linhas é o limite prático |
|
|
||||||
| Banco | SQLite → Oracle ATP | Simples, ACID, sem container extra | Single-machine, ~50 req/s |
|
|
||||||
| Cache | In-memory → Redis | Implícito; migrar quando distribuir | Não compartilhado entre workers |
|
|
||||||
| IaC | Terraform CLI (subprocess) | Testado, familiar | Overhead de processo; file locking |
|
|
||||||
| Charts | Chart.js | Leve, funciona sem React | Customização limitada vs D3 |
|
|
||||||
| Icons | SVG inline (Lucide) | Themeable, consistente | Cherry-picking manual |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Métricas de Referência
|
|
||||||
|
|
||||||
| Arquivo | Linhas | Propósito |
|
|
||||||
|---------|--------|-----------|
|
|
||||||
| backend/app.py | ~7200 | FastAPI server, todos endpoints, state |
|
|
||||||
| frontend-react/src/ | ~15500 | React 19 SPA (42 source files) |
|
|
||||||
| backend/mcp_cis_server.py | ~700 | MCP server, 12 tools CIS |
|
|
||||||
| backend/gen_tf_reference.py | ~70 | Gerador de catálogo Terraform |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. ADB Oracle — Embedding & Vector Search (v2.8+)
|
|
||||||
|
|
||||||
### ACERTOS
|
|
||||||
|
|
||||||
#### 9.1 Auto-mapeamento CSV → tabela ADB
|
|
||||||
- Cada CSV do CIS report mapeia automaticamente para sua tabela: `cis_Identity_*.csv` → `identityandaccess`, `cis_Networking_*.csv` → `networking`, etc.
|
|
||||||
- **Regra**: Quando possível, derive o destino do nome do arquivo. Menos configuração manual = menos erro
|
|
||||||
|
|
||||||
#### 9.2 Purge antes de re-embed
|
|
||||||
- Deletar dados antigos do mesmo tenancy + extract_date antes de inserir novos
|
|
||||||
- Usa `JSON_VALUE(METADATA, '$.tenancy')` para filtrar
|
|
||||||
- **Regra**: Sempre limpe antes de re-inserir. Duplicatas em bases vetoriais poluem resultados
|
|
||||||
|
|
||||||
#### 9.3 Auto-detect dimensão de embedding por tabela
|
|
||||||
- `_get_table_embedding_dim()` → `_DIM_TO_MODEL = {1536: "text-embedding-3-small", 3072: "text-embedding-3-large"}`
|
|
||||||
- Cache de embeddings por modelo: se 5 tabelas usam o mesmo modelo, gera 1 embedding só
|
|
||||||
- **Regra**: Nunca assuma que todas as tabelas têm a mesma dimensão. Detecte dinamicamente
|
|
||||||
|
|
||||||
#### 9.4 Chunking com header de contexto
|
|
||||||
- Textos >8000 chars divididos em partes, cada parte repete header (Tenancy, Resource, ID)
|
|
||||||
- Cada chunk é auto-suficiente para busca vetorial
|
|
||||||
- **Regra**: Chunks sem contexto são inúteis. Sempre repita metadados essenciais
|
|
||||||
|
|
||||||
#### 9.5 Tabelas globais vs tenant-specific
|
|
||||||
- `cisrecom` e `engineerknowledgebase`: busca SEM filtro de tenancy (dados genéricos)
|
|
||||||
- Tabelas de findings: busca COM filtro de tenancy (dados específicos)
|
|
||||||
- **Regra**: Separe dados genéricos de dados específicos. Filtrar dados genéricos por tenancy retorna zero resultados
|
|
||||||
|
|
||||||
#### 9.6 Hierarquia de fontes no RAG
|
|
||||||
- Findings (dados reais) > cisrecom (remediação oficial) > engineerknowledgebase (complementar)
|
|
||||||
- RAG vs MCP Tools: system prompt diferencia dados armazenados vs scan em tempo real
|
|
||||||
- **Regra**: O modelo precisa saber a confiabilidade relativa de cada fonte
|
|
||||||
|
|
||||||
### ERROS
|
|
||||||
|
|
||||||
#### 9.7 ID RAW(16) no ADB
|
|
||||||
- Tabelas usam `ID RAW(16)`, não VARCHAR. Inserts devem usar `HEXTORAW(:1)` com `uuid.uuid4().hex.upper()`
|
|
||||||
- Erro: `ORA-01465: invalid hex number`
|
|
||||||
- **Regra**: Verifique o schema da tabela ANTES de implementar inserts
|
|
||||||
|
|
||||||
#### 9.8 METADATA tipo JSON, não CLOB
|
|
||||||
- `LIKE '%..%'` não funciona com colunas JSON. Usar `JSON_VALUE(METADATA, '$.field') = :1`
|
|
||||||
- Erro: `ORA-01722: unable to convert string containing '%' to a number`
|
|
||||||
- **Regra**: Cada tipo Oracle tem suas funções. JSON → JSON_VALUE/JSON_EXISTS. CLOB → LIKE
|
|
||||||
|
|
||||||
#### 9.9 FETCH FIRST bind variable
|
|
||||||
- Oracle não aceita bind variable no `FETCH FIRST :1 ROWS ONLY`
|
|
||||||
- Usar f-string: `FETCH FIRST {int(n)} ROWS ONLY` (safe pois n é int do Python)
|
|
||||||
- **Regra**: Nem toda cláusula SQL aceita bind variables. Teste cada uso
|
|
||||||
|
|
||||||
#### 9.10 Token limit do modelo de embedding
|
|
||||||
- `text-embedding-3-large` aceita max 8192 tokens. `truncate="END"` do OCI não funciona com modelos OpenAI
|
|
||||||
- Solução: truncar no código Python (8000 chars max) + chunking (8000 chars por parte)
|
|
||||||
- **Regra**: Não confie em flags do SDK para limites. Implemente truncation no seu código
|
|
||||||
|
|
||||||
#### 9.11 Dados legados sem metadata estruturado
|
|
||||||
- Embeddings antigos tinham metadata em formato diferente (`source: blob, blobType, doc_id`), sem campo `tenancy`
|
|
||||||
- Filtro `JSON_VALUE(METADATA, '$.tenancy') IS NULL` incluía esses dados indevidamente
|
|
||||||
- Solução: remover fallback IS NULL, aceitar que dados legados precisam ser re-embedados
|
|
||||||
- **Regra**: Ao mudar schema de metadata, considere migração dos dados existentes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. React Migration & State Management (v2.7→v2.8)
|
|
||||||
|
|
||||||
### ACERTOS
|
|
||||||
|
|
||||||
#### 10.1 Zustand para persistência entre abas
|
|
||||||
- Todas as configurações (model, params, tools, sessions, messages) no Zustand store
|
|
||||||
- Sobrevive navegação entre páginas sem re-fetch
|
|
||||||
- **Regra**: Estado que o usuário espera manter ao voltar → Zustand. Estado transiente (loading, dropdown open) → useState local
|
|
||||||
|
|
||||||
#### 10.2 Code splitting com React.lazy
|
|
||||||
- Bundle de 1.3MB → ~550KB initial load (15 chunks por página)
|
|
||||||
- Suspense fallback com spinner
|
|
||||||
- **Regra**: Implementar lazy loading desde o início. Custo zero de implementação, ganho significativo
|
|
||||||
|
|
||||||
#### 10.3 Background tasks com polling persistente
|
|
||||||
- task_id salvo no Zustand store → polling retoma ao voltar para a página
|
|
||||||
- Status em arquivo no disco (não dict em memória) → visível entre workers
|
|
||||||
- **Regra**: Todo task longo precisa: 1) backend salvar status em disco/DB, 2) frontend salvar task_id no store, 3) retomar polling ao montar
|
|
||||||
|
|
||||||
### ERROS
|
|
||||||
|
|
||||||
#### 10.4 useCallback com closure stale
|
|
||||||
- `sessionId` capturado na closure do useCallback ficava desatualizado
|
|
||||||
- Solução: usar `useAppStore.getState()` para ler valor atual no momento da execução
|
|
||||||
- **Regra**: Em callbacks assíncronos, sempre leia state do store diretamente, nunca da closure
|
|
||||||
|
|
||||||
#### 10.5 setInterval inline no onClick
|
|
||||||
- Não limpa no unmount, pode duplicar. Race condition com estado
|
|
||||||
- Solução: useEffect com cleanup, ou usePolling hook customizado
|
|
||||||
- **Regra**: Nunca crie timers/intervals dentro de event handlers. Sempre use useEffect com cleanup
|
|
||||||
|
|
||||||
#### 10.6 X-Frame-Options DENY bloqueando iframes internos
|
|
||||||
- Security header bloqueava compliance report e HTML report renderizados em iframes
|
|
||||||
- Solução: SAMEORIGIN no bloco /api/ do nginx
|
|
||||||
- **Regra**: Ao adicionar security headers, teste TODOS os fluxos que usam iframes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. Security & Docker Hardening (v2.8)
|
|
||||||
|
|
||||||
### ACERTOS
|
|
||||||
- **Non-root container**: gosu entrypoint para chown do volume + exec como user `agent`
|
|
||||||
- **Security headers nginx**: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy, Permissions-Policy
|
|
||||||
- **Rate limiting**: 10 tentativas/5min por IP com threading.Lock
|
|
||||||
- **CORS restritivo**: métodos/headers explícitos, origins configurável via env
|
|
||||||
- **.gitignore + .dockerignore**: prevenir leak de secrets e reduzir build context
|
|
||||||
- **Graceful shutdown**: terminar subprocesses + executor no shutdown event
|
|
||||||
- **File upload validation**: 50MB max, extensão whitelist por endpoint
|
|
||||||
- **16 SQLite indexes**: em foreign keys e colunas frequentemente consultadas
|
|
||||||
|
|
||||||
### ERROS
|
|
||||||
- **CORS allow_origins=["*"]**: acidentalmente permitia CSRF. Sempre restringir
|
|
||||||
- **Container rodando como root**: padrão do Docker se não especificar USER
|
|
||||||
- **Bare except clauses**: 13 instâncias engolindo erros silenciosamente. Sempre logar
|
|
||||||
- **Sem timeout em chamadas externas**: GenAI e ADB podiam travar indefinidamente. Sempre definir timeout
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. Gaps Conhecidos (para endereçar em projetos futuros)
|
|
||||||
|
|
||||||
1. **Testes automatizados**: Sem cobertura. Pré-requisito para migração PostgreSQL
|
|
||||||
2. **PostgreSQL + Redis**: Planejado para escalar (multi-container, concorrência real)
|
|
||||||
3. **Dashboard real**: Painel com compliance score, atividade recente, status ADB
|
|
||||||
4. **Notificações**: Toast/badge quando tasks longos completam
|
|
||||||
5. **Busca cross-report**: Comparar compliance entre datas
|
|
||||||
6. **Drift detection**: Terraform não detecta mudanças manuais
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13. Recomendações para Próximo Projeto
|
|
||||||
|
|
||||||
1. **Async-first** para qualquer coisa que dependa de LLM
|
|
||||||
2. **SQLite** para começar, migrar quando necessário
|
|
||||||
3. **System prompts compactos** (<3K chars, regras > exemplos)
|
|
||||||
4. **Validação em 3 camadas** para geração de código
|
|
||||||
5. **Cache agressivo** para APIs externas (TTL 2h)
|
|
||||||
6. **CSS variables** para tema desde o dia 1
|
|
||||||
7. **SVG icons** em vez de emojis
|
|
||||||
8. **Framework de componentes** quando ultrapassar ~2K linhas de frontend
|
|
||||||
9. **Auto-update** de ferramentas terceiras no startup do container
|
|
||||||
10. **Guardrails de segurança** (bloquear antes de provisionar, não corrigir silenciosamente)
|
|
||||||
11. **Recovery paths** para todos os estados intermediários
|
|
||||||
12. **Separar fontes de RAG** por agente/contexto
|
|
||||||
13. **Nunca hardcode** valores de infraestrutura — sempre variáveis
|
|
||||||
14. **Documentar deploy patterns** desde o início
|
|
||||||
41
README.md
41
README.md
@@ -31,12 +31,13 @@ The platform combines security compliance scanning, AI-powered chat with **RAG (
|
|||||||
|
|
||||||
### 🤖 AI Chat Agent with RAG + MCP Tool Use
|
### 🤖 AI Chat Agent with RAG + MCP Tool Use
|
||||||
- **OCI Generative AI** integration via official SDK (`oci.generative_ai_inference`)
|
- **OCI Generative AI** integration via official SDK (`oci.generative_ai_inference`)
|
||||||
- **RAG (Retrieval-Augmented Generation)**: automatically queries ADB vector store for relevant context before generating responses
|
- **RAG (Retrieval-Augmented Generation)**: automatically queries ADB vector store for relevant context before generating responses — single ADB connection per search, smart table skip (only queries relevant tables based on question topic), CIS recommendation text filter for exact matching, follow-up context enrichment for short questions
|
||||||
|
- **Source hierarchy**: findings tables > cisrecom (official remediation) > engineerknowledgebase (complementary) — temporal awareness with extract dates, tenancy isolation via JSON_VALUE filter
|
||||||
- **MCP Tool Use (Function Calling)**: GenAI models can call tools from registered MCP servers during chat — supports both Cohere and Generic (OpenAI-style) function calling formats with automatic tool execution loop (max 5 iterations)
|
- **MCP Tool Use (Function Calling)**: GenAI models can call tools from registered MCP servers during chat — supports both Cohere and Generic (OpenAI-style) function calling formats with automatic tool execution loop (max 5 iterations)
|
||||||
- **Chat Memory Compaction**: automatic summarization of older messages when conversation exceeds ~6000 tokens — keeps 20 recent messages (10 interactions) intact and generates an LLM-based summary of older context
|
- **Chat Memory Compaction**: automatic summarization of older messages when conversation exceeds ~6000 tokens — keeps 20 recent messages (10 interactions) intact and generates an LLM-based summary of older context
|
||||||
- **Chat Sidebar**: collapsible right-side panel with model parameters (temperature, max_tokens, top_p, top_k, penalties) for quick adjustment during conversation
|
- **Chat Sidebar**: collapsible right-side panel with model parameters (temperature, max_tokens, top_p, top_k, penalties) for quick adjustment during conversation
|
||||||
- **Multimodal Chat**: upload images (PNG/JPG/GIF/WebP), PDFs, and text files directly in the chat for AI analysis — supports up to 5 files per message via OCI GenAI `ImageContent` and `DocumentContent`
|
- **Multimodal Chat**: upload images (PNG/JPG/GIF/WebP), PDFs, and text files directly in the chat for AI analysis — supports up to 5 files per message via OCI GenAI `ImageContent` and `DocumentContent`
|
||||||
- **Async Background Processing**: chat requests return immediately, GenAI + MCP tools process in background via dedicated thread pool (16 threads), frontend polls for results — eliminates 504 timeouts on long-running scans
|
- **Async Background Processing**: chat requests return immediately, GenAI + MCP tools process in background via dedicated thread pool (10 threads), frontend polls for results — eliminates 504 timeouts on long-running scans
|
||||||
- **Thinking Indicator**: button disables and shows spinner + "Pensando..." while waiting for GenAI response, with message timestamps
|
- **Thinking Indicator**: button disables and shows spinner + "Pensando..." while waiting for GenAI response, with message timestamps
|
||||||
- 16 chat models + 3 embedding models across 5 providers: **Meta** (Llama 4), **Google** (Gemini 2.5), **OpenAI** (GPT-5.2/5.1/5 Mini/4.1/4o, o3/o4-mini), **xAI** (Grok 4/3)
|
- 16 chat models + 3 embedding models across 5 providers: **Meta** (Llama 4), **Google** (Gemini 2.5), **OpenAI** (GPT-5.2/5.1/5 Mini/4.1/4o, o3/o4-mini), **xAI** (Grok 4/3)
|
||||||
- OCID-based model resolution: catalog maps model IDs to OCI resource IDs per region for reliable API calls
|
- OCID-based model resolution: catalog maps model IDs to OCI resource IDs per region for reliable API calls
|
||||||
@@ -65,7 +66,7 @@ The platform combines security compliance scanning, AI-powered chat with **RAG (
|
|||||||
- **Resource type validation**: SQLite-based validation of ~937 OCI resource types with `difflib.get_close_matches` suggestions for invalid types — warnings appended automatically to model responses
|
- **Resource type validation**: SQLite-based validation of ~937 OCI resource types with `difflib.get_close_matches` suggestions for invalid types — warnings appended automatically to model responses
|
||||||
- **Chat history**: ChatGPT-style session history with rename/delete, shared between Chat Agent and Terraform Agent
|
- **Chat history**: ChatGPT-style session history with rename/delete, shared between Chat Agent and Terraform Agent
|
||||||
- **Resizable split view**: chat on top (50%), files/plan/resources + terminal on bottom (50%) with drag-to-resize
|
- **Resizable split view**: chat on top (50%), files/plan/resources + terminal on bottom (50%) with drag-to-resize
|
||||||
- Terraform CLI installed in container (v1.7.5)
|
- Terraform CLI installed in container (v1.14.7)
|
||||||
- **Terraform Resource Reference**: auto-generated OCI provider resource catalog (~937 resources) injected into system prompt — built from `terraform providers schema -json` at container startup, stored in SQLite, refreshable via menu button
|
- **Terraform Resource Reference**: auto-generated OCI provider resource catalog (~937 resources) injected into system prompt — built from `terraform providers schema -json` at container startup, stored in SQLite, refreshable via menu button
|
||||||
- **Official Resource Docs Injection**: on-demand fetch of Example Usage + Argument Reference from the official OCI Terraform provider docs (registry.terraform.io) — cached in SQLite, injected into model context based on detected resource types
|
- **Official Resource Docs Injection**: on-demand fetch of Example Usage + Argument Reference from the official OCI Terraform provider docs (registry.terraform.io) — cached in SQLite, injected into model context based on detected resource types
|
||||||
- **Smart variable resolution**: auto-generates `terraform.tfvars` by scanning declared variables and mapping them to OCI config values (`tenancy_ocid`, `user_ocid`, `fingerprint`, `compartment_id`, `ssh_public_key`) — region is never forced, respecting variable defaults
|
- **Smart variable resolution**: auto-generates `terraform.tfvars` by scanning declared variables and mapping them to OCI config values (`tenancy_ocid`, `user_ocid`, `fingerprint`, `compartment_id`, `ssh_public_key`) — region is never forced, respecting variable defaults
|
||||||
@@ -188,17 +189,19 @@ The platform combines security compliance scanning, AI-powered chat with **RAG (
|
|||||||
- **Case-insensitive table matching**: supports both uppercase and lowercase table names in Oracle ADB with quoted identifiers
|
- **Case-insensitive table matching**: supports both uppercase and lowercase table names in Oracle ADB with quoted identifiers
|
||||||
|
|
||||||
### 🧬 Embeddings & Knowledge Base
|
### 🧬 Embeddings & Knowledge Base
|
||||||
- Dedicated tab for managing vector embeddings and knowledge base
|
- **Auto-embed CIS Reports**: one-click embedding of all report CSVs — each CSV automatically mapped to its ADB table (identityandaccess, networking, computeinstances, etc.)
|
||||||
- **CIS Recommendations**: upload CIS PDF to populate the `cisrecom` vector table with Oracle Cloud security recommendations
|
- **Per-section embedding**: embed individual sections (Identity, Networking, Compute, etc.) with dedicated button per section
|
||||||
- **Knowledge Base (Base de Conhecimento)**: upload documents (`.txt`, `.pdf`, `.csv`, `.json`, `.md`) or **import URLs** (web pages, PDF links) to populate the `engineerknowledgebase` vector table — content is automatically extracted, chunked, and vectorized
|
- **CIS Recommendation tagging**: each embedded document includes CIS recommendation number, section, and status in the content for precise search
|
||||||
- **URL import**: fetches web pages, strips HTML tags/scripts, extracts readable text, and generates embeddings — supports HTML pages and remote PDFs
|
- **Auto-detect embedding dimension**: detects table dimension (1536/3072) and selects correct model automatically
|
||||||
- **Embed CIS Reports**: automatically chunk reports by section with tenancy name, regions, and compartments enrichment, with `report_date` metadata for tracking data freshness
|
- **Purge before re-embed**: automatically deletes old data for same tenancy/date before inserting new embeddings
|
||||||
- **Purge & re-embed**: option to purge old embeddings by tenancy before re-embedding updated reports
|
- **Real-time progress**: progress bar with current section, global progress, queue of upcoming sections
|
||||||
- **Preview chunks before embedding**: review generated sections before creating embeddings
|
- **Background persistence**: embedding continues when navigating away, progress resumes on return
|
||||||
- **OCI GenAI Embeddings**: uses Cohere Embed models (v4.0, multilingual) via OCI GenAI `embed_text` API
|
- **Text chunking**: large CSV rows split into 8000-char chunks with context header (Tenancy, Resource, CIS Recommendation) repeated
|
||||||
- **Consult Embeddings**: dedicated sub-menu under Embeddings with chat-like interface — query the vector store in natural language, AI searches all active tables via cosine similarity and returns contextual answers with source citations
|
- **CIS Recommendations**: upload CIS PDF to populate the `cisrecom` vector table
|
||||||
- Browse and inspect embeddings from the ADB vector store
|
- **Knowledge Base**: upload documents (`.txt`, `.pdf`, `.csv`, `.json`, `.md`) or **import URLs** to populate `engineerknowledgebase`
|
||||||
- 3 embedding models supported: Cohere Embed v4.0, OpenAI Text Embedding 3 Large/Small
|
- **Consult Embeddings**: chat-like interface with tenancy selector — queries vector store with CIS number detection for exact matching, smart table skip, source citations
|
||||||
|
- **OCI GenAI Embeddings**: uses OpenAI Text Embedding 3 Large/Small via OCI GenAI
|
||||||
|
- 11 ADB vector tables supported (9 CIS report + 2 knowledge base)
|
||||||
|
|
||||||
### 📜 Configuration & Chat Logs
|
### 📜 Configuration & Chat Logs
|
||||||
- **Persistent activity log** per configuration tab (OCI, GenAI, ADB, MCP)
|
- **Persistent activity log** per configuration tab (OCI, GenAI, ADB, MCP)
|
||||||
@@ -464,15 +467,15 @@ oci-cis-agent/
|
|||||||
│ ├── cis_reports.py # Oracle CIS Benchmark checker (6660 lines, report engine)
|
│ ├── cis_reports.py # Oracle CIS Benchmark checker (6660 lines, report engine)
|
||||||
│ ├── mcp_cis_server.py # MCP server with 12 granular CIS tools (~700 lines)
|
│ ├── mcp_cis_server.py # MCP server with 12 granular CIS tools (~700 lines)
|
||||||
│ ├── gen_tf_reference.py # OCI Terraform provider resource catalog generator
|
│ ├── gen_tf_reference.py # OCI Terraform provider resource catalog generator
|
||||||
│ ├── Dockerfile # Python 3.12 + OCI CLI + Terraform CLI
|
│ ├── Dockerfile # Python 3.12 + OCI CLI + Terraform 1.14.7 + Chromium
|
||||||
│ └── requirements.txt # Dependencies
|
│ └── requirements.txt # Dependencies
|
||||||
├── frontend-react/
|
├── frontend-react/
|
||||||
│ ├── src/ # React 19 SPA (TypeScript, 38 source files, ~15500 lines)
|
│ ├── src/ # React 19 SPA (TypeScript, 38 source files, ~15500 lines)
|
||||||
│ │ ├── pages/ # 15 page components (Chat, Terraform, Explorer, Reports, Config, Admin)
|
│ │ ├── pages/ # 15 page components (Chat, Terraform, Explorer, Reports, Config, Admin)
|
||||||
│ │ ├── api/ # API client + endpoint modules
|
│ │ ├── api/ # API client + endpoint modules
|
||||||
│ │ ├── stores/ # Zustand auth store
|
│ │ ├── stores/ # Zustand stores (app state persistence across navigation)
|
||||||
│ │ ├── hooks/ # Custom hooks (theme, i18n)
|
│ │ ├── hooks/ # Custom hooks (theme, polling)
|
||||||
│ │ └── i18n/ # Internationalization (pt/en, 625 keys)
|
│ │ └── i18n/ # Internationalization (pt/en, 700+ keys)
|
||||||
│ └── dist/ # Built SPA served at /
|
│ └── dist/ # Built SPA served at /
|
||||||
├── nginx/
|
├── nginx/
|
||||||
│ └── default.conf # Reverse proxy (React SPA + API /api/)
|
│ └── default.conf # Reverse proxy (React SPA + API /api/)
|
||||||
@@ -741,7 +744,7 @@ All models include OCID mapping for `us-ashburn-1`. For other regions, use the "
|
|||||||
| GenAI | `oci.generative_ai_inference` |
|
| GenAI | `oci.generative_ai_inference` |
|
||||||
| Container | Docker Compose, Nginx reverse proxy |
|
| Container | Docker Compose, Nginx reverse proxy |
|
||||||
| MCP | Model Context Protocol SDK (stdio/SSE) with tool discovery + execution |
|
| MCP | Model Context Protocol SDK (stdio/SSE) with tool discovery + execution |
|
||||||
| Terraform | Terraform CLI 1.7.5, OCI Provider |
|
| Terraform | Terraform CLI 1.14.7, OCI Provider |
|
||||||
| CIS Scanner | Oracle CIS Foundations Benchmark 3.0 checker (`cis_reports.py`) |
|
| CIS Scanner | Oracle CIS Foundations Benchmark 3.0 checker (`cis_reports.py`) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
Reference in New Issue
Block a user