Passo 1 v2.0.0: DDL aditivo (ALTER TABLE + RAW_JSON), pronto p/ validação do usuário

- sql/03_v2_ddl_schema_evolution.sql: 23 colunas novas em TB_26AI_TECH_V2 +
  12 em TB_26AI_TECH_CMDB (Tier-1 de ANALISE_DADOS_v1.4.0_gap_schema.md
  seções 2.2/3.1), + RAW_JSON CLOB catch-all em cada tabela. 100% ALTER ADD,
  nenhum DROP, checkpoint de validação embutido.
- TASKS.md: registra o fluxo de trabalho (usuário roda/valida cada passo,
  eu documento) e marca este item como pronto/aguardando execução.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 14:42:01 -03:00
parent b54fcb4f38
commit d37140b36b
2 changed files with 190 additions and 3 deletions

View File

@@ -0,0 +1,178 @@
--------------------------------------------------------------------------------
-- ampmInsights v2.0.0 — Passo 1: DDL de evolução de schema (Fase 1, item 1)
--------------------------------------------------------------------------------
-- O QUE ESTE SCRIPT FAZ
-- Promove os campos "Tier 1" do Tenable/ServiceNow (CVE, CVSS, solução,
-- descrição, pacotes, EPSS, CISA KEV, etc. — ver ANALISE_DADOS_v1.4.0_gap_schema.md
-- seções 2.2 e 3.1) a colunas tipadas em TB_26AI_TECH_V2 e TB_26AI_TECH_CMDB,
-- e adiciona uma coluna RAW_JSON (CLOB) em cada tabela guardando a linha
-- completa do export (99 campos Tenable / 41 campos ServiceNow), para que
-- nada da planilha se perca mesmo fora das colunas tipadas. É a "Opção A
-- (híbrida)" já decidida com o usuário em 2026-08-12.
--
-- O QUE ESTE SCRIPT *NÃO* FAZ (de propósito)
-- - Não dropa, não recria, não trunca nenhuma tabela.
-- - Não altera nenhuma coluna existente (só ADD de colunas novas, todas
-- nullable — carga/app atuais continuam funcionando sem nenhuma mudança).
-- - Não toca em V_26AI_TECH nem em PRC_26AI_TECH (isso é o próximo passo,
-- depende deste aqui já ter rodado).
-- - Não cria TB_26AI_TECH_V2_STG / _HIST (isso é a Fase 1, itens 3-4, script
-- separado).
--
-- COMO RODAR (você, não eu — ver TASKS.md "fluxo de trabalho")
-- 1. Abra Database Actions (ou SQL Developer/SQLcl) conectado como o
-- schema AMPMINSIGHTS — NÃO como ADMIN.
-- 2. IMPORTANTE — decisão pendente: rode isso primeiro em um ambiente que
-- NÃO seja a réplica validada do cliente. Se ainda não existe esse
-- ambiente separado, pare aqui e resolva isso antes (ver TASKS.md,
-- "Fase 2 — Provisionar/receber acesso a um ambiente de teste").
-- 3. Rode o script inteiro de uma vez (ele é idempotente — ver os checks
-- abaixo, pode rodar de novo sem erro se uma coluna já existir).
-- 4. Rode a query de validação no final e confirme que o SELECT retorna
-- as duas tabelas com STATUS = 'OK'.
-- 5. Me traga o resultado dessa query de validação (cole aqui no chat) —
-- só então eu marco este item como concluído no TASKS.md e sigo para
-- o próximo (atualizar V_26AI_TECH + PRC_26AI_TECH).
--
-- ROLLBACK, SE PRECISAR DESFAZER
-- Todas as colunas abaixo são novas e nullable — para desfazer, basta um
-- DROP COLUMN por coluna adicionada (lista no final deste arquivo). Nenhum
-- dado existente é afetado ao reverter.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- 1) TB_26AI_TECH_V2 (vulnerabilidades Tenable) — 23 colunas novas (RAW_JSON incluso)
--------------------------------------------------------------------------------
ALTER TABLE TB_26AI_TECH_V2 ADD (
DEFINITION_CVE VARCHAR2(4000)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Lista de CVEs do achado (definition.cve do Tenable), separadas por virgula. Um achado pode ter mais de uma CVE.'),
DEFINITION_DESCRIPTION CLOB
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Descricao rica do achado (definition.description do Tenable), cita pacote a pacote e CVE a CVE.'),
DEFINITION_SOLUTION CLOB
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Remediacao objetiva sugerida pelo Tenable (definition.solution) - base do plano de acao do AI Insight.'),
DEFINITION_SYNOPSIS VARCHAR2(4000)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Resumo de uma linha do achado (definition.synopsis).'),
SOFTWARE_VULNS CLOB
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Lista de pacotes instalados afetados, com versao e versao corrigida (software_vulns do Tenable). Formato semi-estruturado tipo toString() Java, NAO e JSON valido - ver ANALISE_DADOS_v1.4.0_gap_schema.md secao 2.4.'),
DEFINITION_CVSS3_BASE_SCORE NUMBER
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'CVSS v3 base score (definition.cvss3.base_score) - severidade tecnica padrao de mercado.'),
DEFINITION_CVSS3_BASE_VECTOR VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Vetor CVSS v3 (definition.cvss3.base_vector).'),
DEFINITION_CPE VARCHAR2(4000)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador(es) CPE de produto/pacote afetado (definition.cpe).'),
DEFINITION_EPSS_SCORE NUMBER
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'EPSS score (definition.epss.score) - probabilidade de exploracao real da vulnerabilidade.'),
CISA_KEV_FLAG NUMBER(1)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Flag 1/0 indicando se o achado esta na lista CISA KEV (definition.vpr.drivers_on_cisa_kev) - exploracao ativa conhecida, prioridade maxima.'),
EXPLOITED_BY_MALWARE_FLAG NUMBER(1)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Flag 1/0 indicando exploracao ativa por malware conhecida (definition.exploited_by_malware).'),
EXPLOITED_BY_NESSUS_FLAG NUMBER(1)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Flag 1/0 indicando exploracao confirmada pelo proprio Nessus (definition.exploited_by_nessus).'),
PORT NUMBER
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Porta de rede onde o achado foi identificado (port).'),
ASSET_OPERATING_SYSTEM VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Sistema operacional do ativo, do lado do Tenable (asset.operating_system(s)) - complementa SISTEMA_OPERACIONAL do CMDB.'),
LAST_FIXED TIMESTAMP(9) WITH TIME ZONE
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data em que o achado foi corrigido pela ultima vez (last_fixed).'),
TIME_TO_FIX NUMBER
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Tempo (em dias) que levou para corrigir o achado (time_to_fix).'),
VULN_SLA_DATE TIMESTAMP(9) WITH TIME ZONE
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data-limite de SLA para remediacao do achado (vuln_sla_date).'),
PATCH_PUBLISHED TIMESTAMP(9) WITH TIME ZONE
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data de publicacao do patch corretivo (patch_published).'),
VULNERABILITY_PUBLISHED TIMESTAMP(9) WITH TIME ZONE
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data de publicacao original da vulnerabilidade (vulnerability_published).'),
SOURCE_SCAN VARCHAR2(100)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Origem/fonte do achado (source) - rastreabilidade.'),
SCAN_ID VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador do scan que gerou o achado (scan.id) - rastreabilidade.'),
SCAN_TARGET VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Alvo do scan que gerou o achado (scan.target) - rastreabilidade.'),
RAW_JSON CLOB
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Linha completa do export Tenable (todas as ~99 colunas originais), em JSON, para nao perder nenhum campo mesmo fora das colunas tipadas acima.')
);
--------------------------------------------------------------------------------
-- 2) TB_26AI_TECH_CMDB (ServiceNow) — colunas novas (as 9 "quick win" já
-- existentes de antes NÃO entram aqui — só precisam de perfil de carga
-- novo, sem DDL, ver ANALISE_DADOS_v1.4.0_gap_schema.md seção 3) + RAW_JSON
--------------------------------------------------------------------------------
ALTER TABLE TB_26AI_TECH_CMDB ADD (
INSTALL_STATUS VARCHAR2(100)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Status de instalacao do item de configuracao no ServiceNow (install_status).'),
LIFE_CYCLE_STAGE_STATUS VARCHAR2(100)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Estagio do ciclo de vida do ativo no ServiceNow (life_cycle_stage_status).'),
ASSIGNED_TO VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Pessoa/grupo designado para o ativo no ServiceNow (assigned / assigned_to).'),
ATTESTATION_SCORE NUMBER
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Score de atestacao de inventario do ativo (attestation_score) - sinal de confiabilidade do cadastro.'),
ATTESTATION_STATUS VARCHAR2(100)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Status da atestacao de inventario (attestation_status).'),
ATTESTED_FLAG VARCHAR2(10)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Indicador se o ativo foi atestado (attested).'),
ATTESTED_BY VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Quem atestou o cadastro do ativo (attested_by).'),
U_FIM_DO_SUPORTE DATE
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data de fim de suporte / EOL do ativo (u_fim_do_suporte) - sinal de risco relevante para vulnerability management. CONFIRMAR formato de data do export antes de mapear no perfil de carga.'),
LOCATION VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Localizacao fisica/logica do ativo no ServiceNow (location).'),
ASSET_TAG VARCHAR2(100)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Tag/etiqueta patrimonial do ativo (asset_tag).'),
U_SERVER_ROLE VARCHAR2(255)
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Papel/funcao do servidor (u_server_role).'),
RAW_JSON CLOB
ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Linha completa do export ServiceNow (todas as ~41 colunas originais), em JSON, para nao perder nenhum campo mesmo fora das colunas tipadas.')
);
--------------------------------------------------------------------------------
-- 3) Checkpoint de validação — rode isto depois do ALTER acima e me traga
-- o resultado. Espera-se STATUS = 'OK' nas duas linhas.
--------------------------------------------------------------------------------
SELECT
table_name,
CASE
WHEN table_name = 'TB_26AI_TECH_V2' AND col_count = 23 THEN 'OK'
WHEN table_name = 'TB_26AI_TECH_CMDB' AND col_count = 12 THEN 'OK'
ELSE 'DIVERGENTE - confira manualmente'
END AS status,
col_count AS colunas_novas_encontradas
FROM (
SELECT table_name, COUNT(*) AS col_count
FROM user_tab_columns
WHERE table_name = 'TB_26AI_TECH_V2'
AND column_name IN (
'DEFINITION_CVE','DEFINITION_DESCRIPTION','DEFINITION_SOLUTION','DEFINITION_SYNOPSIS',
'SOFTWARE_VULNS','DEFINITION_CVSS3_BASE_SCORE','DEFINITION_CVSS3_BASE_VECTOR',
'DEFINITION_CPE','DEFINITION_EPSS_SCORE','CISA_KEV_FLAG','EXPLOITED_BY_MALWARE_FLAG',
'EXPLOITED_BY_NESSUS_FLAG','PORT','ASSET_OPERATING_SYSTEM','LAST_FIXED','TIME_TO_FIX',
'VULN_SLA_DATE','PATCH_PUBLISHED','VULNERABILITY_PUBLISHED','SOURCE_SCAN','SCAN_ID',
'SCAN_TARGET','RAW_JSON'
)
GROUP BY table_name
UNION ALL
SELECT table_name, COUNT(*)
FROM user_tab_columns
WHERE table_name = 'TB_26AI_TECH_CMDB'
AND column_name IN (
'INSTALL_STATUS','LIFE_CYCLE_STAGE_STATUS','ASSIGNED_TO','ATTESTATION_SCORE',
'ATTESTATION_STATUS','ATTESTED_FLAG','ATTESTED_BY','U_FIM_DO_SUPORTE','LOCATION',
'ASSET_TAG','U_SERVER_ROLE','RAW_JSON'
)
GROUP BY table_name
);
--------------------------------------------------------------------------------
-- Lista de colunas adicionadas (referência rápida para rollback / doc futura)
--------------------------------------------------------------------------------
-- TB_26AI_TECH_V2 (23): DEFINITION_CVE, DEFINITION_DESCRIPTION, DEFINITION_SOLUTION,
-- DEFINITION_SYNOPSIS, SOFTWARE_VULNS, DEFINITION_CVSS3_BASE_SCORE,
-- DEFINITION_CVSS3_BASE_VECTOR, DEFINITION_CPE, DEFINITION_EPSS_SCORE,
-- CISA_KEV_FLAG, EXPLOITED_BY_MALWARE_FLAG, EXPLOITED_BY_NESSUS_FLAG, PORT,
-- ASSET_OPERATING_SYSTEM, LAST_FIXED, TIME_TO_FIX, VULN_SLA_DATE,
-- PATCH_PUBLISHED, VULNERABILITY_PUBLISHED, SOURCE_SCAN, SCAN_ID, SCAN_TARGET,
-- RAW_JSON
-- TB_26AI_TECH_CMDB (12): INSTALL_STATUS, LIFE_CYCLE_STAGE_STATUS, ASSIGNED_TO,
-- ATTESTATION_SCORE, ATTESTATION_STATUS, ATTESTED_FLAG, ATTESTED_BY,
-- U_FIM_DO_SUPORTE, LOCATION, ASSET_TAG, U_SERVER_ROLE, RAW_JSON