Files
knowledge-one-view-cli/docs/tests.html

1074 lines
49 KiB
HTML

<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Knowledge One View CLI - Testes</title>
<style>
:root {
--bg: #f6f4ef;
--card: #fffdf8;
--ink: #1f2523;
--muted: #5e6864;
--line: #d8d2c8;
--brand: #0f766e;
--brand-soft: #d8efe9;
--accent: #b25a28;
--accent-soft: #f5e2d6;
--ok: #137333;
--ok-soft: #e7f4ea;
--warn: #8a5a00;
--warn-soft: #fff4d6;
--code-bg: #f1eee7;
--shadow: 0 10px 26px rgba(31, 37, 35, 0.08);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
color: var(--ink);
background:
radial-gradient(circle at top left, rgba(15, 118, 110, 0.11), transparent 22%),
radial-gradient(circle at right top, rgba(178, 90, 40, 0.1), transparent 18%),
var(--bg);
line-height: 1.5;
}
a { color: var(--brand); }
p, li, td, th { overflow-wrap: anywhere; }
code {
font-family: Consolas, "Courier New", monospace;
font-size: 0.88em;
background: var(--code-bg);
padding: 2px 6px;
border-radius: 7px;
}
.lang-page { display: none; }
.lang-page.active { display: block; }
.page {
display: grid;
grid-template-columns: 250px minmax(0, 1fr);
min-height: 100vh;
}
.sidebar {
position: sticky;
top: 0;
align-self: start;
height: 100vh;
padding: 20px 16px;
border-right: 1px solid var(--line);
background: rgba(255, 253, 248, 0.92);
backdrop-filter: blur(10px);
}
.language-switch {
display: grid;
gap: 8px;
margin-bottom: 18px;
}
.language-button {
display: flex;
align-items: center;
justify-content: center;
min-height: 52px;
padding: 12px 14px;
border-radius: 16px;
border: 1px solid var(--line);
background: var(--card);
color: var(--ink);
cursor: pointer;
font-size: 0.95rem;
font-weight: 800;
letter-spacing: 0.02em;
box-shadow: var(--shadow);
transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.language-button:hover {
transform: translateY(-1px);
border-color: var(--brand);
}
.language-button.active {
background: linear-gradient(135deg, rgba(216, 239, 233, 0.95), rgba(255, 253, 248, 0.98));
border-color: var(--brand);
color: var(--brand);
}
.brand small,
.eyebrow,
.pill,
.badge {
display: inline-flex;
align-items: center;
border-radius: 999px;
padding: 4px 8px;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.03em;
text-transform: uppercase;
}
.brand small {
background: var(--brand-soft);
color: var(--brand);
}
.brand h1 {
margin: 10px 0 8px;
font-size: 1.35rem;
line-height: 1.1;
}
.brand p,
.sidebar-note,
.section-lead,
.card p,
.metric p,
.footer,
.muted {
color: var(--muted);
font-size: 0.9rem;
}
.nav {
display: grid;
gap: 6px;
margin-top: 18px;
}
.nav a {
text-decoration: none;
color: var(--ink);
border: 1px solid transparent;
border-radius: 10px;
padding: 8px 10px;
font-weight: 650;
}
.nav a:hover {
background: rgba(255, 255, 255, 0.75);
border-color: var(--line);
}
.sidebar-note {
margin-top: 18px;
padding: 12px;
border-radius: 14px;
border: 1px solid var(--line);
background: var(--card);
box-shadow: var(--shadow);
}
main { padding: 24px; }
.hero,
.section,
.footer {
max-width: 1240px;
margin: 0 auto 18px;
}
.hero-card,
.panel,
.table-wrap,
.code-wrap,
.card {
background: var(--card);
border: 1px solid var(--line);
border-radius: 18px;
box-shadow: var(--shadow);
}
.hero-card {
padding: 22px 24px;
background: linear-gradient(135deg, rgba(255, 253, 248, 0.97), rgba(216, 239, 233, 0.86));
}
.eyebrow {
background: var(--accent-soft);
color: var(--accent);
}
.hero h2 {
margin: 10px 0 8px;
font-size: clamp(1.7rem, 3vw, 2.7rem);
line-height: 1.05;
max-width: 940px;
}
.section h2 {
margin: 0 0 4px;
font-size: 1.4rem;
}
.section-lead {
margin: 0 0 10px;
max-width: 940px;
}
.grid-4,
.grid-2 {
display: grid;
gap: 10px;
}
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.metric,
.card {
padding: 14px;
border-radius: 16px;
border: 1px solid var(--line);
background: rgba(255, 255, 255, 0.72);
}
.kpi {
font-size: 1.55rem;
font-weight: 800;
line-height: 1;
margin-bottom: 8px;
color: var(--brand);
}
.panel,
.code-wrap {
padding: 16px;
}
.table-wrap {
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
min-width: 1160px;
}
th,
td {
padding: 7px 8px;
text-align: left;
vertical-align: top;
border-bottom: 1px solid var(--line);
font-size: 0.78rem;
line-height: 1.35;
}
th {
font-size: 0.66rem;
text-transform: uppercase;
letter-spacing: 0.03em;
background: rgba(216, 239, 233, 0.52);
color: #26312f;
white-space: nowrap;
}
tr:last-child td { border-bottom: none; }
.badge {
border: 1px solid transparent;
white-space: nowrap;
font-size: 0.64rem;
}
.pass {
color: var(--ok);
background: var(--ok-soft);
}
.skip {
color: var(--warn);
background: var(--warn-soft);
}
.mode {
color: var(--brand);
background: var(--brand-soft);
}
.commands {
display: grid;
gap: 10px;
margin-top: 10px;
}
pre {
margin: 0;
padding: 12px;
overflow-x: auto;
max-width: 100%;
background: #fbfaf6;
color: var(--ink);
border-radius: 14px;
border: 1px solid var(--line);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
font-size: 0.86rem;
line-height: 1.45;
}
pre code {
display: block;
padding: 0;
background: transparent;
border-radius: 0;
color: inherit;
font-size: 1em;
white-space: pre;
}
.footer {
padding: 6px 0 20px;
text-align: center;
}
@media (max-width: 1180px) {
.page { grid-template-columns: 1fr; }
.sidebar {
position: static;
height: auto;
border-right: none;
border-bottom: 1px solid var(--line);
}
.grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
main { padding: 14px; }
.hero-card, .panel { padding: 16px; }
.grid-4 { grid-template-columns: 1fr; }
table { min-width: 920px; }
}
</style>
</head>
<body>
<div class="lang-page active" data-lang-page="pt">
<div class="page">
<aside class="sidebar">
<div class="language-switch" aria-label="Seletor de idioma">
<button class="language-button active" type="button" data-lang-target="pt">Português</button>
<button class="language-button" type="button" data-lang-target="es">Español</button>
</div>
<div class="brand">
<small>Test Report</small>
<h1>Knowledge One View CLI</h1>
<p>Relatório humano da suíte de testes, com foco no que cada teste prova de fato.</p>
</div>
<nav class="nav">
<a href="#pt-overview">Visão Geral</a>
<a href="#pt-method">Metodologia</a>
<a href="#pt-offline">Offline</a>
<a href="#pt-live">Live</a>
<a href="#pt-commands">Comandos</a>
</nav>
<div class="sidebar-note">
Esta página vive em <code>docs/tests.html</code>. O estilo segue o guia consolidado em <code>docs/docs.html</code>.
</div>
</aside>
<main>
<section class="hero" id="pt-overview">
<div class="hero-card">
<span class="eyebrow">node:test</span>
<h2>O que a suíte valida antes de confiar nos dados.</h2>
<p class="section-lead">
O modo offline prova contratos, roteamento, SQL, escopo e transformações locais. O modo live confirma
que os comandos documentados continuam executando contra o Oracle DV com a sessão atual.
</p>
<div class="grid-4">
<div class="metric"><div class="kpi">12/12</div><p>testes offline passaram</p></div>
<div class="metric"><div class="kpi">13/13</div><p>testes live passaram</p></div>
<div class="metric"><div class="kpi">0</div><p>falhas na última execução</p></div>
<div class="metric"><div class="kpi">2026-04-26</div><p>data registrada</p></div>
</div>
</div>
</section>
<section class="section" id="pt-method">
<h2>Metodologia</h2>
<p class="section-lead">
Os testes usam <code>node:test</code>. Eles leem <code>SKILL.md</code>, <code>references/script-catalog.md</code>,
<code>references/initial-context-catalog.md</code> e <code>references/api-map.md</code> como fonte da verdade,
evitando uma cópia paralela de parâmetros e regras dentro da própria suíte.
</p>
<div class="grid-2">
<div class="card">
<span class="pill mode">Offline</span>
<p>Não chama o Oracle DV. Testa se a CLI escolhe o caminho certo, monta os filtros certos e preserva o contrato de saída.</p>
</div>
<div class="card">
<span class="pill mode">Live</span>
<p>Chama o Oracle DV com <code>--no-cache</code>. O runtime de autenticação é copiado para uma área temporária de teste.</p>
</div>
</div>
</section>
<section class="section" id="pt-offline">
<h2>Testes offline</h2>
<p class="section-lead">
Estes testes respondem: "a skill monta a consulta e a resposta certas?". Eles não provam disponibilidade
do Oracle DV nem volume real de dados.
</p>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Teste</th>
<th>Objetivo</th>
<th>Entrada</th>
<th>Resultado esperado</th>
<th>Saída observada</th>
<th>Status</th>
<th>Avaliação</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>date-window</code></td>
<td>Validar atalhos de data e rejeição de combinações inválidas.</td>
<td><code>resolveDateWindow</code> com <code>--date</code>, <code>--month</code>, <code>--quarter</code>, <code>--week</code> e conflito.</td>
<td>Ranges conforme catálogo e erro para argumentos conflitantes.</td>
<td><code>single=2026-05-02</code>; <code>month=2026-04-01..2026-04-30</code>; <code>quarter=2026-03-01..2026-05-31</code>; <code>week=2026-03-22..2026-03-28</code>; inválido rejeitado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>sa-attach-defaults</code></td>
<td>Confirmar defaults e aliases de SA Attach vindos do catálogo inicial.</td>
<td><code>parseSaAttachDefaults</code>, <code>parseSaAttachAliases</code> e <code>resolveSaAttachFilters</code>.</td>
<td>Cluster, soluções, status, LOBs, tipos de receita e aliases aplicados.</td>
<td><code>cluster=Brazil</code>; <code>solutions=3</code>; <code>statuses=3</code>; aliases validados.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>current-workload-defaults</code></td>
<td>Verificar os defaults dos intents de workload atual.</td>
<td><code>applyCurrentWorkloadIntentDefaults</code> para owner atual e mês explícito.</td>
<td><code>current-quarter</code>, <code>Cloud Infrastructure - Workloads</code> e <code>WORKLOAD</code>; mês explícito preservado.</td>
<td><code>quarter=current-quarter</code>; <code>solution=Cloud Infrastructure - Workloads</code>; <code>revenueTypeGroup=WORKLOAD</code>; mês preservado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>sa-attach-window-sql</code></td>
<td>Evitar regressão no campo usado para filtro de close date.</td>
<td><code>buildSaAttachOpportunityWhereClauses</code> com janela <code>2026-03-01..2026-05-31</code>.</td>
<td>Usar <code>Revenue Line Close Date</code>, incluir forecast/owner e não usar <code>Revenue Line Close Year</code>.</td>
<td>Campo correto usado; forecast/owner incluídos; <code>Revenue Line Close Year</code> ausente.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>scope-sql</code></td>
<td>Validar regras de escopo org-wide e my-team nos SQLs gerados.</td>
<td><code>renderViewSql</code> para Presales Aux, Hours e <code>srs-by-resource-email</code>.</td>
<td>Org-wide sem <code>SEC_ARIA</code>; my-team com <code>SEC_ARIA</code>; SR por recurso usa levels 1..4; lead só quando explícito.</td>
<td>Regras confirmadas para org-wide, my-team, SR team e lead explícito.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>current-team-summary</code></td>
<td>Garantir que oportunidades sem cobertura do time continuam no resultado misto.</td>
<td><code>summarizeCurrentTeamOpportunityCoverage</code> com 2 oportunidades e 1 cobertura.</td>
<td>2 records; 1 matched; 1 unmatched; totais comerciais preservados.</td>
<td><code>records=2</code>; <code>matched=1</code>; <code>unmatched=1</code>; <code>totalWorkload=125000</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>manager-resource-summary</code></td>
<td>Validar resumo org-wide por manager/recurso e enriquecimento opcional com SRs.</td>
<td><code>summarizeOrgWideRevenueLineCoverage</code> com cobertura Aux e cenário com SR injetado.</td>
<td>Recursos preservados; SR omitido por padrão; SR direto e candidato interno distinguidos quando injetados.</td>
<td><code>defaultResourceDetails=2</code>; SR omitido; linkage <code>direct-plus-candidate-internal</code>; <code>resourcesMatched=2</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>api-metrics</code></td>
<td>Confirmar que métricas contam linhas brutas do backend, não cache local.</td>
<td><code>buildApiMetrics</code> com resultados de 3 + 2 linhas e uma leitura local.</td>
<td><code>totalRowsPulledFromApi=5</code>; cache local ignorado no total.</td>
<td><code>totalRowsPulledFromApi=5</code>; <code>queries=3</code>; cache local ignorado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>sales prompt commands</code></td>
<td>Verificar se prompts comuns viram comandos CLI curtos, diretos e documentados.</td>
<td>Casos de <code>tests/prompts/sales-prompts.json</code>.</td>
<td>Um modo por comando; sem discovery desnecessário; flags documentadas; intents citados nas referências.</td>
<td>Todos os prompts seguiram o contrato esperado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>people examples</code></td>
<td>Evitar e-mails fake hard-coded nos prompts de teste.</td>
<td>Serialização dos prompts e placeholders esperados.</td>
<td>Usar placeholders como <code>{{resourceManagerEmail}}</code>, <code>{{territoryOwnerEmail}}</code> e <code>{{resourceMember}}</code>.</td>
<td>Placeholders dinâmicos encontrados; e-mails fake padrão não apareceram.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>intent CLI contract</code></td>
<td>Garantir que comandos de intent batem com o contrato exposto pela própria CLI.</td>
<td><code>--list-parameters</code> e <code>--describe-intent</code> para intents usados nos prompts.</td>
<td>Flags existem no catálogo global e no contrato do intent; defaults atuais documentados.</td>
<td>Contratos bateram; defaults de workload atual e descrição do intent manager/resource validados.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
<tr>
<td><code>ad-hoc-query</code></td>
<td>Confirmar que query ad hoc renderiza como leitura org-wide de oportunidades.</td>
<td><code>--query --select opportunityId,customerName,closeDate,bookingValue,workloadAmount --where "closeDate = DATE '2026-05-02'" --render-sql</code>.</td>
<td>Modo query; escopo org-wide; fonte comercial primária; sem <code>SEC_ARIA</code>; aliases documentados.</td>
<td>Query org-wide renderizada na fonte comercial primária, sem fallback para <code>DV - SE Team</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correto.</td>
</tr>
</tbody>
</table>
</div>
</section>
<section class="section" id="pt-live">
<h2>Testes live</h2>
<p class="section-lead">
Estes testes confirmam execução real contra o Oracle DV com <code>--no-cache</code>. A tabela mostra os prompts
com placeholders, porque os e-mails reais são resolvidos dinamicamente durante a execução.
</p>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Caso</th>
<th>Prompt executado</th>
<th>Objetivo</th>
<th>Comando validado</th>
<th>Resultado esperado</th>
<th>Última saída</th>
<th>Status</th>
<th>Escopo</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>generic-pipeline</code></td>
<td>Me traga o pipeline de oportunidades no Knowledge One View.</td>
<td>Validar leitura genérica de pipeline.</td>
<td><code>--intent opportunities-default --limit 1000</code></td>
<td>Fonte comercial primária, org-wide, sem fallback, pelo menos 100 registros.</td>
<td><code>records=1000</code>; <code>apiRows=1000</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>exact-close-date</code></td>
<td>Quais oportunidades fecham em 2026-05-02?</td>
<td>Validar close date exato.</td>
<td><code>--intent opportunities-close-date --date 2026-05-02 --limit 1000</code></td>
<td>Fonte comercial primária, org-wide, sem fallback, pelo menos 1 registro.</td>
<td><code>records=11</code>; <code>apiRows=11</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>calendar-month</code></td>
<td>Quais oportunidades fecham em abril de 2026?</td>
<td>Validar janela de mês calendário.</td>
<td><code>--intent opportunities-close-month --month 2026-04 --limit 1000</code></td>
<td>Fonte comercial primária, org-wide, sem fallback, pelo menos 11 registros.</td>
<td><code>records=1000</code>; <code>apiRows=1000</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>manager-week</code></td>
<td>Quais oportunidades do manager <code>{{resourceManagerEmail}}</code> fecham na week 43?</td>
<td>Validar oportunidades por manager de recurso em uma week.</td>
<td><code>--intent opportunities-by-manager-close-window --manager-email {{resourceManagerEmail}} --week w43 --week-year 2025 --limit 10</code></td>
<td>Comercial org-wide com alocação via Presales Aux; sem fallback.</td>
<td><code>records=10</code>; <code>apiRows=11</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Opportunities org-wide + Presales Involvement Aux org-wide.</td>
</tr>
<tr>
<td><code>owner-workload-current</code></td>
<td>Me mostre os workloads em forecast agora do vendedor <code>{{territoryOwnerEmail}}</code>.</td>
<td>Validar workloads em forecast para vendedor.</td>
<td><code>--intent workloads-by-owner-current --owner-email {{territoryOwnerEmail}} --forecast-type Forecast --limit 10</code></td>
<td>Fonte comercial primária, org-wide, sem fallback.</td>
<td><code>records=1</code>; <code>apiRows=1</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>owner-manager-workload-current</code></td>
<td>Quais workloads em forecast agora dos owners abaixo de <code>{{territoryManagerEmail}}</code>?</td>
<td>Validar workloads para owners sob manager comercial.</td>
<td><code>--intent workloads-by-owner-manager-current --owner-manager-email {{territoryManagerEmail}} --forecast-type Forecast --limit 10</code></td>
<td>Fonte comercial primária, org-wide, sem fallback.</td>
<td><code>records=9</code>; <code>apiRows=9</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>manager-resource-next-7-days</code></td>
<td>Workloads com close date nos próximos 7 dias em oportunidades com recursos abaixo de <code>{{resourceManagerEmailA}}</code> e <code>{{resourceManagerEmailB}}</code>.</td>
<td>Validar workloads próximos por managers de recurso.</td>
<td><code>--intent workloads-by-manager-resource-close-window --manager-email-list {{resourceManagerEmailList}} --from-date today --to-date +7d --limit 10</code></td>
<td>Comercial org-wide, alocação org-wide por Presales Aux, sem consultas a <code>DV - SE Team</code>.</td>
<td><code>records=4</code>; <code>apiRows=15</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Opportunities org-wide + Presales Involvement Aux org-wide.</td>
</tr>
<tr>
<td><code>resource-srs</code></td>
<td>Quais SRs estão com <code>{{resourceMember}}</code> agora?</td>
<td>Validar busca de SRs por recurso.</td>
<td><code>--intent srs-by-resource --resource {{resourceMember}} --limit 10</code></td>
<td>Leitura em <code>DV - SE Team</code>, escopo my-team-only, array de records válido.</td>
<td><code>records=0</code>; <code>apiRows=0</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>DV - SE Team; my-team-only.</td>
</tr>
<tr>
<td><code>current-team-close-window</code></td>
<td>Quais oportunidades fecham nos próximos 4 dias e têm recursos do meu time?</td>
<td>Validar oportunidades org-wide enriquecidas com recursos do time atual.</td>
<td><code>--intent opportunities-current-team-close-window --from-date today --to-date +4d --limit 10</code></td>
<td>Escopo mixed-consistent; oportunidades org-wide; recursos do time atual; linhas sem match preservadas.</td>
<td><code>records=10</code>; <code>apiRows=12</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Opportunities org-wide + resources current team.</td>
</tr>
</tbody>
</table>
</div>
</section>
<section class="section" id="pt-commands">
<div class="code-wrap">
<h2>Como executar</h2>
<p class="section-lead">
Rode a partir de <code>/Users/marceloarbore/.codex/skills/knowledge-one-view-cli</code>. Nesta máquina,
o shell do agente usou o Node do runtime do Codex porque <code>node</code> não estava no <code>PATH</code>.
</p>
<div class="commands">
<pre><code>node tests/run.mjs</code></pre>
<pre><code>KNOWLEDGE_ONE_VIEW_LIVE=1 \
ORACLE_SI_RUNTIME_HOME=/Users/marceloarbore/code/fusion/knowledge-one-view-cli/runtime \
node tests/run.mjs</code></pre>
<pre><code>/Users/marceloarbore/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node tests/run.mjs</code></pre>
</div>
</div>
</section>
<p class="footer">
Documento de leitura rápida da suíte. Para a documentação completa da skill, veja <a href="docs.html">docs.html</a>.
</p>
</main>
</div>
</div>
<div class="lang-page" data-lang-page="es">
<div class="page">
<aside class="sidebar">
<div class="language-switch" aria-label="Selector de idioma">
<button class="language-button" type="button" data-lang-target="pt">Português</button>
<button class="language-button active" type="button" data-lang-target="es">Español</button>
</div>
<div class="brand">
<small>Test Report</small>
<h1>Knowledge One View CLI</h1>
<p>Reporte humano de la suite de pruebas, enfocado en lo que cada prueba demuestra realmente.</p>
</div>
<nav class="nav">
<a href="#es-overview">Vista General</a>
<a href="#es-method">Metodología</a>
<a href="#es-offline">Offline</a>
<a href="#es-live">Live</a>
<a href="#es-commands">Comandos</a>
</nav>
<div class="sidebar-note">
Esta página vive en <code>docs/tests.html</code>. El estilo sigue la guía consolidada en <code>docs/docs.html</code>.
</div>
</aside>
<main>
<section class="hero" id="es-overview">
<div class="hero-card">
<span class="eyebrow">node:test</span>
<h2>Qué valida la suite antes de confiar en los datos.</h2>
<p class="section-lead">
El modo offline prueba contratos, ruteo, SQL, alcance y transformaciones locales. El modo live confirma
que los comandos documentados siguen ejecutándose contra Oracle DV con la sesión actual.
</p>
<div class="grid-4">
<div class="metric"><div class="kpi">12/12</div><p>pruebas offline aprobadas</p></div>
<div class="metric"><div class="kpi">13/13</div><p>pruebas live aprobadas</p></div>
<div class="metric"><div class="kpi">0</div><p>fallas en la última ejecución</p></div>
<div class="metric"><div class="kpi">2026-04-26</div><p>fecha registrada</p></div>
</div>
</div>
</section>
<section class="section" id="es-method">
<h2>Metodología</h2>
<p class="section-lead">
Las pruebas usan <code>node:test</code>. Leen <code>SKILL.md</code>, <code>references/script-catalog.md</code>,
<code>references/initial-context-catalog.md</code> y <code>references/api-map.md</code> como fuente de verdad,
evitando duplicar parámetros y reglas dentro de la suite.
</p>
<div class="grid-2">
<div class="card">
<span class="pill mode">Offline</span>
<p>No llama a Oracle DV. Verifica que la CLI elija el camino correcto, arme filtros correctos y preserve el contrato de salida.</p>
</div>
<div class="card">
<span class="pill mode">Live</span>
<p>Llama a Oracle DV con <code>--no-cache</code>. El runtime de autenticación se copia a un área temporal de prueba.</p>
</div>
</div>
</section>
<section class="section" id="es-offline">
<h2>Pruebas offline</h2>
<p class="section-lead">
Estas pruebas responden: "la skill arma la consulta y la respuesta correctas?". No prueban disponibilidad
de Oracle DV ni volumen real de datos.
</p>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Prueba</th>
<th>Objetivo</th>
<th>Entrada</th>
<th>Resultado esperado</th>
<th>Salida observada</th>
<th>Status</th>
<th>Evaluación</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>date-window</code></td>
<td>Validar atajos de fecha y rechazo de combinaciones inválidas.</td>
<td><code>resolveDateWindow</code> con <code>--date</code>, <code>--month</code>, <code>--quarter</code>, <code>--week</code> y conflicto.</td>
<td>Rangos según catálogo y error para argumentos conflictivos.</td>
<td><code>single=2026-05-02</code>; <code>month=2026-04-01..2026-04-30</code>; <code>quarter=2026-03-01..2026-05-31</code>; <code>week=2026-03-22..2026-03-28</code>; inválido rechazado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>sa-attach-defaults</code></td>
<td>Confirmar defaults y aliases de SA Attach desde el catálogo inicial.</td>
<td><code>parseSaAttachDefaults</code>, <code>parseSaAttachAliases</code> y <code>resolveSaAttachFilters</code>.</td>
<td>Cluster, soluciones, status, LOBs, tipos de ingreso y aliases aplicados.</td>
<td><code>cluster=Brazil</code>; <code>solutions=3</code>; <code>statuses=3</code>; aliases validados.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>current-workload-defaults</code></td>
<td>Verificar los defaults de los intents de workload actual.</td>
<td><code>applyCurrentWorkloadIntentDefaults</code> para owner actual y mes explícito.</td>
<td><code>current-quarter</code>, <code>Cloud Infrastructure - Workloads</code> y <code>WORKLOAD</code>; mes explícito preservado.</td>
<td><code>quarter=current-quarter</code>; <code>solution=Cloud Infrastructure - Workloads</code>; <code>revenueTypeGroup=WORKLOAD</code>; mes preservado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>sa-attach-window-sql</code></td>
<td>Evitar regresión en el campo usado para filtro de close date.</td>
<td><code>buildSaAttachOpportunityWhereClauses</code> con ventana <code>2026-03-01..2026-05-31</code>.</td>
<td>Usar <code>Revenue Line Close Date</code>, incluir forecast/owner y no usar <code>Revenue Line Close Year</code>.</td>
<td>Campo correcto usado; forecast/owner incluidos; <code>Revenue Line Close Year</code> ausente.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>scope-sql</code></td>
<td>Validar reglas de alcance org-wide y my-team en SQL generado.</td>
<td><code>renderViewSql</code> para Presales Aux, Hours y <code>srs-by-resource-email</code>.</td>
<td>Org-wide sin <code>SEC_ARIA</code>; my-team con <code>SEC_ARIA</code>; SR por recurso usa levels 1..4; lead solo si es explícito.</td>
<td>Reglas confirmadas para org-wide, my-team, SR team y lead explícito.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>current-team-summary</code></td>
<td>Garantizar que oportunidades sin cobertura del equipo continúan en el resultado mixto.</td>
<td><code>summarizeCurrentTeamOpportunityCoverage</code> con 2 oportunidades y 1 cobertura.</td>
<td>2 records; 1 matched; 1 unmatched; totales comerciales preservados.</td>
<td><code>records=2</code>; <code>matched=1</code>; <code>unmatched=1</code>; <code>totalWorkload=125000</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>manager-resource-summary</code></td>
<td>Validar resumen org-wide por manager/recurso y enriquecimiento opcional con SRs.</td>
<td><code>summarizeOrgWideRevenueLineCoverage</code> con cobertura Aux y escenario con SR inyectado.</td>
<td>Recursos preservados; SR omitido por defecto; SR directo y candidato interno distinguidos cuando se inyectan.</td>
<td><code>defaultResourceDetails=2</code>; SR omitido; linkage <code>direct-plus-candidate-internal</code>; <code>resourcesMatched=2</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>api-metrics</code></td>
<td>Confirmar que métricas cuentan filas brutas del backend, no cache local.</td>
<td><code>buildApiMetrics</code> con resultados de 3 + 2 filas y una lectura local.</td>
<td><code>totalRowsPulledFromApi=5</code>; cache local ignorado en el total.</td>
<td><code>totalRowsPulledFromApi=5</code>; <code>queries=3</code>; cache local ignorado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>sales prompt commands</code></td>
<td>Verificar si prompts comunes se convierten en comandos CLI cortos, directos y documentados.</td>
<td>Casos de <code>tests/prompts/sales-prompts.json</code>.</td>
<td>Un modo por comando; sin discovery innecesario; flags documentadas; intents citados en referencias.</td>
<td>Todos los prompts siguieron el contrato esperado.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>people examples</code></td>
<td>Evitar e-mails fake hard-coded en los prompts de prueba.</td>
<td>Serialización de prompts y placeholders esperados.</td>
<td>Usar placeholders como <code>{{resourceManagerEmail}}</code>, <code>{{territoryOwnerEmail}}</code> y <code>{{resourceMember}}</code>.</td>
<td>Placeholders dinámicos encontrados; e-mails fake estándar no aparecieron.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>intent CLI contract</code></td>
<td>Garantizar que comandos de intent coinciden con el contrato expuesto por la CLI.</td>
<td><code>--list-parameters</code> y <code>--describe-intent</code> para intents usados en prompts.</td>
<td>Flags existen en el catálogo global y en el contrato del intent; defaults actuales documentados.</td>
<td>Contratos coinciden; defaults de workload actual y descripción del intent manager/resource validados.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
<tr>
<td><code>ad-hoc-query</code></td>
<td>Confirmar que query ad hoc renderiza como lectura org-wide de oportunidades.</td>
<td><code>--query --select opportunityId,customerName,closeDate,bookingValue,workloadAmount --where "closeDate = DATE '2026-05-02'" --render-sql</code>.</td>
<td>Modo query; alcance org-wide; fuente comercial primaria; sin <code>SEC_ARIA</code>; aliases documentados.</td>
<td>Query org-wide renderizada en la fuente comercial primaria, sin fallback a <code>DV - SE Team</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Correcto.</td>
</tr>
</tbody>
</table>
</div>
</section>
<section class="section" id="es-live">
<h2>Pruebas live</h2>
<p class="section-lead">
Estas pruebas confirman ejecución real contra Oracle DV con <code>--no-cache</code>. La tabla muestra los prompts
con placeholders porque los e-mails reales se resuelven dinámicamente durante la ejecución.
</p>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Caso</th>
<th>Prompt ejecutado</th>
<th>Objetivo</th>
<th>Comando validado</th>
<th>Resultado esperado</th>
<th>Última salida</th>
<th>Status</th>
<th>Alcance</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>generic-pipeline</code></td>
<td>Me traga o pipeline de oportunidades no Knowledge One View.</td>
<td>Validar lectura genérica de pipeline.</td>
<td><code>--intent opportunities-default --limit 1000</code></td>
<td>Fuente comercial primaria, org-wide, sin fallback, al menos 100 registros.</td>
<td><code>records=1000</code>; <code>apiRows=1000</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>exact-close-date</code></td>
<td>Quais oportunidades fecham em 2026-05-02?</td>
<td>Validar close date exacto.</td>
<td><code>--intent opportunities-close-date --date 2026-05-02 --limit 1000</code></td>
<td>Fuente comercial primaria, org-wide, sin fallback, al menos 1 registro.</td>
<td><code>records=11</code>; <code>apiRows=11</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>calendar-month</code></td>
<td>Quais oportunidades fecham em abril de 2026?</td>
<td>Validar ventana de mes calendario.</td>
<td><code>--intent opportunities-close-month --month 2026-04 --limit 1000</code></td>
<td>Fuente comercial primaria, org-wide, sin fallback, al menos 11 registros.</td>
<td><code>records=1000</code>; <code>apiRows=1000</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>manager-week</code></td>
<td>Quais oportunidades do manager <code>{{resourceManagerEmail}}</code> fecham na week 43?</td>
<td>Validar oportunidades por manager de recurso en una week.</td>
<td><code>--intent opportunities-by-manager-close-window --manager-email {{resourceManagerEmail}} --week w43 --week-year 2025 --limit 10</code></td>
<td>Comercial org-wide con asignación por Presales Aux; sin fallback.</td>
<td><code>records=10</code>; <code>apiRows=11</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Opportunities org-wide + Presales Involvement Aux org-wide.</td>
</tr>
<tr>
<td><code>owner-workload-current</code></td>
<td>Me mostre os workloads em forecast agora do vendedor <code>{{territoryOwnerEmail}}</code>.</td>
<td>Validar workloads en forecast para vendedor.</td>
<td><code>--intent workloads-by-owner-current --owner-email {{territoryOwnerEmail}} --forecast-type Forecast --limit 10</code></td>
<td>Fuente comercial primaria, org-wide, sin fallback.</td>
<td><code>records=1</code>; <code>apiRows=1</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>owner-manager-workload-current</code></td>
<td>Quais workloads em forecast agora dos owners abaixo de <code>{{territoryManagerEmail}}</code>?</td>
<td>Validar workloads para owners bajo manager comercial.</td>
<td><code>--intent workloads-by-owner-manager-current --owner-manager-email {{territoryManagerEmail}} --forecast-type Forecast --limit 10</code></td>
<td>Fuente comercial primaria, org-wide, sin fallback.</td>
<td><code>records=9</code>; <code>apiRows=9</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Knowledge DV - Opportunities - V2; org-wide.</td>
</tr>
<tr>
<td><code>manager-resource-next-7-days</code></td>
<td>Workloads com close date nos próximos 7 dias em oportunidades com recursos abaixo de <code>{{resourceManagerEmailA}}</code> e <code>{{resourceManagerEmailB}}</code>.</td>
<td>Validar workloads próximos por managers de recurso.</td>
<td><code>--intent workloads-by-manager-resource-close-window --manager-email-list {{resourceManagerEmailList}} --from-date today --to-date +7d --limit 10</code></td>
<td>Comercial org-wide, asignación org-wide por Presales Aux, sin consultas a <code>DV - SE Team</code>.</td>
<td><code>records=4</code>; <code>apiRows=15</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Opportunities org-wide + Presales Involvement Aux org-wide.</td>
</tr>
<tr>
<td><code>resource-srs</code></td>
<td>Quais SRs estão com <code>{{resourceMember}}</code> agora?</td>
<td>Validar búsqueda de SRs por recurso.</td>
<td><code>--intent srs-by-resource --resource {{resourceMember}} --limit 10</code></td>
<td>Lectura en <code>DV - SE Team</code>, alcance my-team-only, array de records válido.</td>
<td><code>records=0</code>; <code>apiRows=0</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>DV - SE Team; my-team-only.</td>
</tr>
<tr>
<td><code>current-team-close-window</code></td>
<td>Quais oportunidades fecham nos próximos 4 dias e têm recursos do meu time?</td>
<td>Validar oportunidades org-wide enriquecidas con recursos del equipo actual.</td>
<td><code>--intent opportunities-current-team-close-window --from-date today --to-date +4d --limit 10</code></td>
<td>Alcance mixed-consistent; oportunidades org-wide; recursos del equipo actual; filas sin match preservadas.</td>
<td><code>records=10</code>; <code>apiRows=12</code>.</td>
<td><span class="badge pass">PASS</span></td>
<td>Opportunities org-wide + resources current team.</td>
</tr>
</tbody>
</table>
</div>
</section>
<section class="section" id="es-commands">
<div class="code-wrap">
<h2>Cómo ejecutar</h2>
<p class="section-lead">
Ejecutar desde <code>/Users/marceloarbore/.codex/skills/knowledge-one-view-cli</code>. En esta máquina,
el shell del agente usó Node del runtime de Codex porque <code>node</code> no estaba en el <code>PATH</code>.
</p>
<div class="commands">
<pre><code>node tests/run.mjs</code></pre>
<pre><code>KNOWLEDGE_ONE_VIEW_LIVE=1 \
ORACLE_SI_RUNTIME_HOME=/Users/marceloarbore/code/fusion/knowledge-one-view-cli/runtime \
node tests/run.mjs</code></pre>
<pre><code>/Users/marceloarbore/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node tests/run.mjs</code></pre>
</div>
</div>
</section>
<p class="footer">
Documento de lectura rápida de la suite. Para la documentación completa de la skill, vea <a href="docs.html">docs.html</a>.
</p>
</main>
</div>
</div>
<script>
(function () {
const STORAGE_KEY = "knowledge-one-view-cli-tests-lang";
const pages = Array.from(document.querySelectorAll("[data-lang-page]"));
const buttons = Array.from(document.querySelectorAll("[data-lang-target]"));
const html = document.documentElement;
function setLanguage(lang) {
pages.forEach((page) => {
page.classList.toggle("active", page.getAttribute("data-lang-page") === lang);
});
buttons.forEach((button) => {
const isActive = button.getAttribute("data-lang-target") === lang;
button.classList.toggle("active", isActive);
button.setAttribute("aria-pressed", String(isActive));
});
html.lang = lang === "es" ? "es-ES" : "pt-BR";
try {
localStorage.setItem(STORAGE_KEY, lang);
} catch (error) {
}
window.scrollTo({ top: 0, behavior: "auto" });
}
let initialLang = "pt";
try {
const saved = localStorage.getItem(STORAGE_KEY);
if (saved === "pt" || saved === "es") {
initialLang = saved;
}
} catch (error) {
}
buttons.forEach((button) => {
button.addEventListener("click", () => {
setLanguage(button.getAttribute("data-lang-target"));
});
});
setLanguage(initialLang);
})();
</script>
</body>
</html>