From 3c050c25a74572aacdce02dd860e35d52f91eae3 Mon Sep 17 00:00:00 2001 From: Moretto <72614882+Giomoret@users.noreply.github.com> Date: Mon, 14 Sep 2026 13:49:13 -0300 Subject: [PATCH] =?UTF-8?q?feat(seed):=20adiciona=20acervo=20hist=C3=B3ric?= =?UTF-8?q?o=20curado=20e=20pol=C3=ADtica=20de=20dados=20(PRE-06)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adiciona recorte documental dos projetos API-1, API-2 e API-3 com origem por URL, revisão e hash. Implementa carga transacional e idempotente com proteção contra sobrescrita. Documenta a política de dados e os limites da curadoria, e adiciona testes e validação do seed na CI. Validação: 6 testes passaram com PostgreSQL real, build concluído e carga repetida sem duplicação. Pendências: revisão do PR, execução remota da CI e carga no ambiente escolhido. Nenhuma alteração realizada na base atual. --- .github/workflows/ci.yml | 39 +++ backend/package.json | 3 + backend/src/database/seed-lib.ts | 83 +++++ backend/src/database/seed.test.ts | 50 +++ backend/src/database/seed.ts | 30 ++ database/seed/POLITICA_DE_DADOS.md | 60 ++++ database/seed/README.md | 42 +++ database/seed/curated/api-1-backlog-23.md | 7 + database/seed/curated/api-1-backlog-35.md | 7 + database/seed/curated/api-2-us-01.md | 7 + database/seed/curated/api-2-us-02.md | 7 + database/seed/curated/api-3-grf-01.md | 7 + database/seed/curated/api-3-grf-08.md | 7 + database/seed/fixtures/historical-v1.json | 387 ++++++++++++++++++++++ database/seed/validation-cases.json | 11 + 15 files changed, 747 insertions(+) create mode 100644 backend/src/database/seed-lib.ts create mode 100644 backend/src/database/seed.test.ts create mode 100644 backend/src/database/seed.ts create mode 100644 database/seed/POLITICA_DE_DADOS.md create mode 100644 database/seed/curated/api-1-backlog-23.md create mode 100644 database/seed/curated/api-1-backlog-35.md create mode 100644 database/seed/curated/api-2-us-01.md create mode 100644 database/seed/curated/api-2-us-02.md create mode 100644 database/seed/curated/api-3-grf-01.md create mode 100644 database/seed/curated/api-3-grf-08.md create mode 100644 database/seed/fixtures/historical-v1.json create mode 100644 database/seed/validation-cases.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06df114..896e205 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,45 @@ on: - develop jobs: + validate-seed: + name: Validate curated seed on PostgreSQL + runs-on: ubuntu-latest + services: + postgres: + image: pgvector/pgvector:pg16 + env: + POSTGRES_USER: seed_test + POSTGRES_PASSWORD: seed_test_only + POSTGRES_DB: sinapse_seed_test + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U seed_test -d sinapse_seed_test" + --health-interval 5s --health-timeout 5s --health-retries 10 + env: + NODE_ENV: test + POSTGRES_HOST: localhost + POSTGRES_PORT: 5432 + POSTGRES_USER: seed_test + POSTGRES_PASSWORD: seed_test_only + POSTGRES_DB: sinapse_seed_test + SEED_TEST_DATABASE_URL: postgresql://seed_test:seed_test_only@localhost:5432/sinapse_seed_test + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: npm + cache-dependency-path: backend/package-lock.json + - run: npm ci + working-directory: backend + - run: npm run migrate + working-directory: backend + - run: npm run seed:validate + working-directory: backend + - run: npm run test:seed + working-directory: backend + validate-environment: name: Validate Workflows and Docker Setup runs-on: ubuntu-latest diff --git a/backend/package.json b/backend/package.json index 8025558..28ca440 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,6 +5,9 @@ "private": true, "main": "dist/index.js", "scripts": { + "seed:validate": "tsx src/database/seed.ts --validate", + "seed:apply": "tsx src/database/seed.ts --apply", + "test:seed": "tsx --test src/database/seed.test.ts", "dev": "tsx watch src/index.ts", "build": "tsc", "start": "node dist/index.js", diff --git a/backend/src/database/seed-lib.ts b/backend/src/database/seed-lib.ts new file mode 100644 index 0000000..66942a1 --- /dev/null +++ b/backend/src/database/seed-lib.ts @@ -0,0 +1,83 @@ +import { createHash } from "node:crypto"; +import { readFile } from "node:fs/promises"; +import { resolve } from "node:path"; +import { isDeepStrictEqual } from "node:util"; +import type { PoolClient } from "pg"; + +const fields: Record = { + projeto: ["id", "nome", "cliente", "descricao", "status"], + documento: ["id", "projeto_id", "nome", "mime", "caminho", "status_processamento"], + chunk: ["id", "projeto_id", "entidade_tipo", "entidade_id", "texto", "metadados_json"], +}; +export interface SeedRecord { table: string; values: Record; source: Record } +export interface Dataset { dataset: string; version: number; source_decision: Record; records: SeedRecord[] } +export const fixturePath = resolve(process.cwd(), "../database/seed/fixtures/historical-v1.json"); + +export function validateDataset(input: unknown): asserts input is Dataset { + const data = input as Dataset; + if (data?.dataset !== "pre06-historical-v1" || data.version !== 1 || !data.source_decision?.decision || !Array.isArray(data.records) || !data.records.length) throw new Error("Manifesto inválido"); + const seen = new Map(); + for (const row of data.records) { + const columns = fields[row.table]; + if (!columns || !row.values || !isDeepStrictEqual(Object.keys(row.values).sort(), [...columns].sort())) throw new Error("Tabela ou campos não permitidos"); + const id = row.values.id; + if (typeof id !== "string" || !/^60000000-0000-4000-8000-\d{12}$/.test(id) || seen.has(id)) throw new Error("ID inválido ou duplicado"); + const source = row.source; + if (!source || !/^https:\/\/github.com\/Galaticos-API\/API-[123]$/.test(source.repository) + || !/^[a-f0-9]{40}$/.test(source.revision) || !/^[a-f0-9]{64}$/.test(source.source_sha256) + || !/^(readme\.md|DOCS\/Documentação das Sprints\/DocSprint1\.md|DOCS\/analise_backend\/analiseRequisitosBackend\.md)$/.test(source.path) + || !source.locator || source.classification !== "curated-public-documentation" + || !source.transformation || !source.url?.startsWith(`${source.repository}/blob/${source.revision}/`)) throw new Error("Origem ausente ou não permitida"); + if (row.table === "documento") { + if (seen.get(String(row.values.projeto_id))?.table !== "projeto") throw new Error("Projeto de documento inválido"); + if (!/^database\/seed\/curated\/[a-z0-9-]+\.md$/.test(String(row.values.caminho))) throw new Error("Caminho não permitido"); + } + if (row.table === "chunk") { + const parent = seen.get(String(row.values.entidade_id)); + const metadata = row.values.metadados_json as Record; + if (row.values.entidade_tipo !== "documento" || parent?.table !== "documento" || parent.values.projeto_id !== row.values.projeto_id + || metadata?.dataset !== data.dataset || metadata.source_url !== source.url || metadata.embedding_status !== "pending") throw new Error("Chunk sem isolamento ou origem"); + } + seen.set(id, row); + } +} + +export async function loadDataset(): Promise { + const data: unknown = JSON.parse(await readFile(fixturePath, "utf8")); + validateDataset(data); + for (const row of data.records.filter(row => row.table === "documento")) { + const text = await readFile(resolve(process.cwd(), "..", String(row.values.caminho)), "utf8"); + if (!text.includes(row.source.url)) throw new Error("Documento curado sem referência"); + } + return data; +} + +export function validateTarget(url: string | undefined, environment: string | undefined): string { + if (!url || environment === "production") throw new Error("Seed restrito a banco de desenvolvimento/teste explícito"); + const target = new URL(url); + if (!["postgres:", "postgresql:"].includes(target.protocol) || !/_(dev|test)$/.test(decodeURIComponent(target.pathname))) throw new Error("Banco deve terminar em _dev ou _test"); + return url; +} + +// Caller owns BEGIN/COMMIT/ROLLBACK. No partial application, update or deletion. +export async function applyDataset(client: PoolClient, data: Dataset): Promise { + validateDataset(data); + await client.query("SELECT pg_advisory_xact_lock(604006)"); + for (const row of data.records) { + const keys = fields[row.table]; + const id = String(row.values.id); + const auditId = id.replace(/^60000000/, "61000000"); + const evidence = { dataset: data.dataset, version: data.version, source: row.source, + payload_sha256: createHash("sha256").update(JSON.stringify(row.values)).digest("hex") }; + const existing = await client.query(`SELECT ${keys.join(",")} FROM ${row.table} WHERE id = $1`, [id]); + const audit = await client.query("SELECT dados_json FROM auditoria WHERE id = $1", [auditId]); + if (existing.rowCount) { + if (!isDeepStrictEqual(existing.rows[0], row.values) || !isDeepStrictEqual(audit.rows[0]?.dados_json, evidence)) throw new Error("Colisão ou divergência em registro do seed; nenhuma sobrescrita realizada"); + continue; + } + if (audit.rowCount) throw new Error("Origem existente sem registro correspondente"); + await client.query(`INSERT INTO ${row.table} (${keys.join(",")}) VALUES (${keys.map((_, i) => `$${i + 1}`).join(",")})`, keys.map(key => row.values[key])); + await client.query("INSERT INTO auditoria (id, entidade_tipo, entidade_id, acao, justificativa, dados_json) VALUES ($1,$2,$3,'seed_import',$4,$5)", + [auditId, row.table, id, "PRE-06: carga curada de documentação pública; origem registrada", evidence]); + } +} diff --git a/backend/src/database/seed.test.ts b/backend/src/database/seed.test.ts new file mode 100644 index 0000000..f8bfe15 --- /dev/null +++ b/backend/src/database/seed.test.ts @@ -0,0 +1,50 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { applyDataset, loadDataset, validateDataset, validateTarget } from "./seed-lib.js"; +import { Pool } from "pg"; + +test("acervo curado contém três projetos, seis documentos e seis chunks com origem", async () => { + const data = await loadDataset(); + assert.equal(data.records.filter(row => row.table === "projeto").length, 3); + assert.equal(data.records.filter(row => row.table === "documento").length, 6); + assert.equal(data.records.filter(row => row.table === "chunk").length, 6); + assert.equal(data.records.some(row => ["usuario", "competencia", "alocacao"].includes(row.table)), false); +}); +test("recusa registro sem origem", async () => { + const data = await loadDataset(); data.records[0].source.revision = ""; + assert.throws(() => validateDataset(data)); +}); +test("recusa mistura de projetos nos chunks", async () => { + const data = await loadDataset(); data.records.find(row => row.table === "chunk")!.values.projeto_id = "outro"; + assert.throws(() => validateDataset(data)); +}); +test("recusa tabelas e caminhos fora da curadoria", async () => { + const data = await loadDataset(); data.records[0].table = "usuario"; + assert.throws(() => validateDataset(data)); + const other = await loadDataset(); other.records.find(row => row.table === "documento")!.values.caminho = "../../secret"; + assert.throws(() => validateDataset(other)); +}); +test("recusa produção, destino ausente e banco não dedicado", () => { + assert.throws(() => validateTarget(undefined, "test")); + assert.throws(() => validateTarget("postgresql://localhost/acervo_test", "production")); + assert.throws(() => validateTarget("postgresql://localhost/sinapse", "development")); + assert.equal(validateTarget("postgresql://localhost/acervo_test", "test"), "postgresql://localhost/acervo_test"); +}); +test("carga SQL é idempotente e recusa sobrescrita", { skip: !process.env.SEED_TEST_DATABASE_URL }, async () => { + const pool = new Pool({ connectionString: validateTarget(process.env.SEED_TEST_DATABASE_URL, "test") }); + const client = await pool.connect(); + try { + await client.query("BEGIN"); + const data = await loadDataset(); + await applyDataset(client, data); + await applyDataset(client, data); + const count = await client.query("SELECT count(*)::int AS total FROM auditoria WHERE dados_json->>'dataset' = $1", [data.dataset]); + assert.equal(count.rows[0].total, 15); + await client.query("SAVEPOINT collision"); + const changed = structuredClone(data); changed.records[0].values.nome = "Alterado"; + await assert.rejects(applyDataset(client, changed)); + await client.query("ROLLBACK TO SAVEPOINT collision"); + const stored = await client.query("SELECT nome FROM projeto WHERE id = $1", [data.records[0].values.id]); + assert.equal(stored.rows[0].nome, data.records[0].values.nome); + } finally { await client.query("ROLLBACK"); client.release(); await pool.end(); } +}); diff --git a/backend/src/database/seed.ts b/backend/src/database/seed.ts new file mode 100644 index 0000000..ddfa185 --- /dev/null +++ b/backend/src/database/seed.ts @@ -0,0 +1,30 @@ +import { Pool } from "pg"; +import { applyDataset, loadDataset, validateTarget } from "./seed-lib.js"; + +async function main() { + const mode = process.argv[2] ?? "--validate"; + if (!["--validate", "--apply"].includes(mode)) throw new Error("Modo inválido"); + const data = await loadDataset(); + if (mode === "--validate") { + console.log(`[Seed] Manifesto e documentos válidos: ${data.records.length} registros.`); + return; + } + const connectionString = validateTarget(process.env.SEED_DATABASE_URL, process.env.NODE_ENV); + const pool = new Pool({ connectionString, connectionTimeoutMillis: 5000 }); + try { + const client = await pool.connect(); + try { + await client.query("BEGIN"); + await applyDataset(client, data); + await client.query("COMMIT"); + console.log(`[Seed] Carga concluída: ${data.records.length} registros com origem.`); + } catch (error) { await client.query("ROLLBACK"); throw error; } + finally { client.release(); } + } finally { await pool.end(); } +} + +main().catch(() => { + // Never dump connection strings, database details or source payloads to logs. + console.error("[Seed] Falha na validação/carga. Confira migrações, banco permitido e colisões; transação não confirmada."); + process.exitCode = 1; +}); diff --git a/database/seed/POLITICA_DE_DADOS.md b/database/seed/POLITICA_DE_DADOS.md new file mode 100644 index 0000000..d938ecf --- /dev/null +++ b/database/seed/POLITICA_DE_DADOS.md @@ -0,0 +1,60 @@ +# Política de dados iniciais — PRE-06 + +## Decisão e finalidade + +Em 14/09/2026, o solicitante confirmou nesta tarefa o uso de API-1, API-2 e API-3, +seguindo a origem D3 registrada em `docs/backlog/README.md`. Não foi adotado Plano B +fictício. Finalidade: desenvolvimento e validação local de busca e reúso documental. +A base é um recorte de requisitos públicos, não uma cópia dos sistemas anteriores. + +## Curadoria aplicada + +- API-1: `readme.md`, itens 23 e 35 do backlog (acesso administrativo e gráficos). +- API-2: `DOCS/Documentação das Sprints/DocSprint1.md`, US-01 e US-02. +- API-3: `DOCS/analise_backend/analiseRequisitosBackend.md`, GRF-01 e GRF-08. + +Entram apenas resumos dos requisitos selecionados. Ficam fora autores, nomes de +colaboradores, contatos, clientes identificáveis, código-fonte, configuração de IDE, +segredos, anexos de teste, imagens de atestados, avaliações individuais e documentos +brutos. Os clientes aparecem como “Organização não identificada”; não existe tabela +de correspondência com pessoas no seed. Referências aos repositórios são mantidas +para rastreabilidade, portanto não se promete anonimização absoluta das fontes públicas. + +Os textos são resumos produzidos com assistência de IA, sujeitos à revisão do PR. +Não foram convertidos em histórias ou critérios adicionais que não existam nas fontes. +Links, revisões e hashes identificam a evidência consultada, sem importar o documento +inteiro nem os dados de exemplos operacionais. O hash registra o texto fonte obtido +em UTF-8; não é uma alegação de aprovação jurídica ou de conteúdo íntegro de um PDF. + +## Origem e integridade + +Cada entidade possui origem no manifesto e um evento determinístico `seed_import` +na tabela `auditoria`. Chunks também carregam URL, revisão e hash nos metadados. +Eventos não recebem autor humano fictício; `usuario_id` permanece nulo e a seleção +das fontes fica documentada no manifesto. O carregador usa parâmetros SQL e emite +somente contagens ou erro genérico, sem URLs de conexão ou payloads em logs. + +## Uso e limitações + +A escolha das fontes foi autorizada pelo solicitante. A revisão humana do recorte +deve ocorrer no PR antes de sua distribuição. O carregador é restrito a ambientes +de desenvolvimento/teste; não usar em produção ou em base compartilhada de cliente. + +Não se infere competência individual a partir de tecnologias do repositório. Não +foram carregados usuários, alocações ou competências pessoais; consultas “quem +trabalhou com X?” devem retornar ausência de evidência individual. Para demonstrar +respostas positivas do PBI-05.2.1, o time ainda precisa fornecer evidência de alocação +curada e autorizada, sem inventar vínculos entre pessoas e requisitos. + +Busca semântica exige embeddings reais. Os chunks têm vetor nulo e metadado +`embedding_status=pending`; documentos continuam `pendente` para indexação. Os casos +de validação descrevem expectativas do acervo, não resultados de um motor já testado. + +## Revisão, retenção e retirada + +Toda ampliação exige origem versionada, curadoria de dados pessoais e revisão por +outra pessoa. Não importar diretórios inteiros. Se uma fonte precisar ser retirada, +identificar seus IDs pelo manifesto, revisar referências e excluir conteúdo e +vetores em uma migração aprovada; preservar apenas a trilha de retirada necessária, +sem reter conteúdo sensível no evento. Ambientes descartáveis devem ser eliminados +ao final dos testes. Nunca apagar ou alterar silenciosamente dados fora do dataset. diff --git a/database/seed/README.md b/database/seed/README.md index 6ac9468..63d52aa 100644 --- a/database/seed/README.md +++ b/database/seed/README.md @@ -1,8 +1,50 @@ # Seed de desenvolvimento +## PRE-06 — Acervo histórico curado + +O seed atual é `fixtures/historical-v1.json`, aplicado pelo backend. Contém três +projetos acadêmicos API-1/API-2/API-3, seis resumos de requisitos e seis chunks sem +vetores. As cópias curadas ficam em `curated/`. Não há pessoas, credenciais ou +competências inventadas. Cada registro tem repositório, revisão, caminho, localização, +hash SHA-256 do texto fonte em UTF-8 e descrição da transformação; a carga persiste +essa origem em `auditoria` e nos metadados dos chunks. + +Dentro de `backend`, execute `npm ci`, `npm run seed:validate` e `npm run test:seed`. +Para carregar, prepare um banco dedicado com as migrações 001–003. Configure +`SEED_DATABASE_URL` por variável de ambiente (não em argumentos nem arquivos versionados) +e execute `npm run seed:apply`. O nome do banco deve terminar em `_dev` ou `_test`; +`NODE_ENV=production` é recusado. O comando de migração existente usa suas próprias +variáveis `POSTGRES_*`; confira que apontam para o mesmo banco dedicado antes de migrar. + +O modo padrão só valida arquivos. A aplicação é transacional, serializada e +idempotente: repetir não duplica registros/auditoria; colisões ou alteração de +conteúdo/origem interrompem a operação, sem sobrescrever dados do usuário. Não há +remoção automática. Para atualizar o acervo, criar versão revisada e migração explícita. + +`test:seed` verifica o manifesto sem PostgreSQL. Se `SEED_TEST_DATABASE_URL` estiver +definida, também testa a carga duas vezes em uma transação revertida ao final e a +recusa de divergência. A CI fornece PostgreSQL 16 + pgvector dedicado e executa as +migrações antes desse teste. Sem a variável, o teste SQL aparece como ignorado; +isso não equivale a validação da carga real. + +Leia [POLITICA_DE_DADOS.md](POLITICA_DE_DADOS.md) e [validation-cases.json](validation-cases.json). +Embeddings não são fabricados: a indexação real continua pendente do pipeline da IA. + +Validação local: manifesto e documentos aprovados pelo validador, build do backend +concluído e 6 testes da PRE-06 passaram com PostgreSQL 16 + pgvector descartável, +sem testes ignorados. O comando `seed:apply` também foi executado duas vezes com +sucesso: 3 projetos, 6 documentos, 6 chunks e 15 eventos de origem, sem duplicação. +O banco de teste foi removido; nenhuma carga foi feita na base corrente do projeto. +A execução remota da CI e a revisão humana do PR continuam pendentes. + +## Seed fictício legado + `dev_seed.sql` contém somente dados fictícios e determinísticos para desenvolvimento local e demonstrações. Não use este arquivo em produção e não inclua dados reais, tokens, senhas ou documentos de clientes. O seed é idempotente: pode ser executado novamente sem duplicar os registros com os mesmos identificadores. + +O arquivo legado é mantido por compatibilidade, não faz parte da carga histórica +PRE-06 e não deve ser executado junto com ela para demonstrar o acervo curado. diff --git a/database/seed/curated/api-1-backlog-23.md b/database/seed/curated/api-1-backlog-23.md new file mode 100644 index 0000000..7a2acef --- /dev/null +++ b/database/seed/curated/api-1-backlog-23.md @@ -0,0 +1,7 @@ +# Acesso administrativo + +O backlog prevê login para administradores, restringindo o acesso às funcionalidades destinadas aos responsáveis. + +Origem: https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L68 + +Classificação: resumo curado de documentação pública. Não comprova implementação em produção nem experiência individual. diff --git a/database/seed/curated/api-1-backlog-35.md b/database/seed/curated/api-1-backlog-35.md new file mode 100644 index 0000000..ffa6207 --- /dev/null +++ b/database/seed/curated/api-1-backlog-35.md @@ -0,0 +1,7 @@ +# Métricas de equipe em gráficos + +O backlog prevê gráficos de avaliação para apoiar a análise do desempenho de equipes. + +Origem: https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L74 + +Classificação: resumo curado de documentação pública. Não comprova implementação em produção nem experiência individual. diff --git a/database/seed/curated/api-2-us-01.md b/database/seed/curated/api-2-us-01.md new file mode 100644 index 0000000..1a36e75 --- /dev/null +++ b/database/seed/curated/api-2-us-01.md @@ -0,0 +1,7 @@ +# Administrar acesso de usuários + +A documentação da primeira sprint descreve cadastro, consulta, edição e inativação de usuários pelo RH para administrar o acesso à plataforma. + +Origem: https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L43 + +Classificação: resumo curado de documentação pública. Não comprova implementação em produção nem experiência individual. diff --git a/database/seed/curated/api-2-us-02.md b/database/seed/curated/api-2-us-02.md new file mode 100644 index 0000000..6575f66 --- /dev/null +++ b/database/seed/curated/api-2-us-02.md @@ -0,0 +1,7 @@ +# Registrar plano individual por ano + +A documentação descreve criação de um plano de desenvolvimento individual associado a um colaborador e a um ano, preservando o histórico de planos. + +Origem: https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L44 + +Classificação: resumo curado de documentação pública. Não comprova implementação em produção nem experiência individual. diff --git a/database/seed/curated/api-3-grf-01.md b/database/seed/curated/api-3-grf-01.md new file mode 100644 index 0000000..fb00981 --- /dev/null +++ b/database/seed/curated/api-3-grf-01.md @@ -0,0 +1,7 @@ +# Visualizar saldo de crédito nacional + +A análise de requisitos prevê gráfico de linha do saldo nacional de crédito, usando as séries 20539, 20540 e 20541. + +Origem: https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L6 + +Classificação: resumo curado de documentação pública. Não comprova implementação em produção nem experiência individual. diff --git a/database/seed/curated/api-3-grf-08.md b/database/seed/curated/api-3-grf-08.md new file mode 100644 index 0000000..396aaf8 --- /dev/null +++ b/database/seed/curated/api-3-grf-08.md @@ -0,0 +1,7 @@ +# Comparar oportunidades por estado + +A análise de requisitos prevê gráfico de barras do índice de oportunidade, com pontuação entre zero e dez e ordenação por estado. + +Origem: https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L13 + +Classificação: resumo curado de documentação pública. Não comprova implementação em produção nem experiência individual. diff --git a/database/seed/fixtures/historical-v1.json b/database/seed/fixtures/historical-v1.json new file mode 100644 index 0000000..75299d1 --- /dev/null +++ b/database/seed/fixtures/historical-v1.json @@ -0,0 +1,387 @@ +{ + "dataset": "pre06-historical-v1", + "version": 1, + "source_decision": { + "selected_by": "Solicitante da PRE-06 nesta tarefa", + "decision": "Usar documentação dos projetos API-1, API-2 e API-3, conforme confirmação explícita.", + "date": "2026-09-14", + "review": "pending_pull_request" + }, + "records": [ + { + "table": "projeto", + "values": { + "id": "60000000-0000-4000-8000-000000000001", + "nome": "PRE06 — Acervo API-1", + "cliente": "Organização não identificada", + "descricao": "Recorte documental curado do projeto API-1; não é cópia integral nem avaliação de pessoas.", + "status": "ativo" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-1", + "revision": "1edd3096e46cb1cb9c794dbaec887a83487c0e97", + "path": "readme.md", + "source_sha256": "a1591b42d9f7c266e6be7cfec43bf0ec06164c56ee8d22933dedb3a4c227a37c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "Backlog 23", + "url": "https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L68" + } + }, + { + "table": "documento", + "values": { + "id": "60000000-0000-4000-8000-000000000002", + "projeto_id": "60000000-0000-4000-8000-000000000001", + "nome": "API-1 — Acesso administrativo", + "mime": "text/markdown", + "caminho": "database/seed/curated/api-1-backlog-23.md", + "status_processamento": "pendente" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-1", + "revision": "1edd3096e46cb1cb9c794dbaec887a83487c0e97", + "path": "readme.md", + "source_sha256": "a1591b42d9f7c266e6be7cfec43bf0ec06164c56ee8d22933dedb3a4c227a37c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "Backlog 23", + "url": "https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L68" + } + }, + { + "table": "chunk", + "values": { + "id": "60000000-0000-4000-8000-000000000003", + "projeto_id": "60000000-0000-4000-8000-000000000001", + "entidade_tipo": "documento", + "entidade_id": "60000000-0000-4000-8000-000000000002", + "texto": "O backlog prevê login para administradores, restringindo o acesso às funcionalidades destinadas aos responsáveis.", + "metadados_json": { + "dataset": "pre06-historical-v1", + "source_url": "https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L68", + "source_revision": "1edd3096e46cb1cb9c794dbaec887a83487c0e97", + "source_sha256": "a1591b42d9f7c266e6be7cfec43bf0ec06164c56ee8d22933dedb3a4c227a37c", + "classification": "curated-public-documentation", + "embedding_status": "pending", + "individual_experience": "not_evidenced" + } + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-1", + "revision": "1edd3096e46cb1cb9c794dbaec887a83487c0e97", + "path": "readme.md", + "source_sha256": "a1591b42d9f7c266e6be7cfec43bf0ec06164c56ee8d22933dedb3a4c227a37c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "Backlog 23", + "url": "https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L68" + } + }, + { + "table": "documento", + "values": { + "id": "60000000-0000-4000-8000-000000000004", + "projeto_id": "60000000-0000-4000-8000-000000000001", + "nome": "API-1 — Métricas de equipe em gráficos", + "mime": "text/markdown", + "caminho": "database/seed/curated/api-1-backlog-35.md", + "status_processamento": "pendente" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-1", + "revision": "1edd3096e46cb1cb9c794dbaec887a83487c0e97", + "path": "readme.md", + "source_sha256": "a1591b42d9f7c266e6be7cfec43bf0ec06164c56ee8d22933dedb3a4c227a37c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "Backlog 35", + "url": "https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L74" + } + }, + { + "table": "chunk", + "values": { + "id": "60000000-0000-4000-8000-000000000005", + "projeto_id": "60000000-0000-4000-8000-000000000001", + "entidade_tipo": "documento", + "entidade_id": "60000000-0000-4000-8000-000000000004", + "texto": "O backlog prevê gráficos de avaliação para apoiar a análise do desempenho de equipes.", + "metadados_json": { + "dataset": "pre06-historical-v1", + "source_url": "https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L74", + "source_revision": "1edd3096e46cb1cb9c794dbaec887a83487c0e97", + "source_sha256": "a1591b42d9f7c266e6be7cfec43bf0ec06164c56ee8d22933dedb3a4c227a37c", + "classification": "curated-public-documentation", + "embedding_status": "pending", + "individual_experience": "not_evidenced" + } + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-1", + "revision": "1edd3096e46cb1cb9c794dbaec887a83487c0e97", + "path": "readme.md", + "source_sha256": "a1591b42d9f7c266e6be7cfec43bf0ec06164c56ee8d22933dedb3a4c227a37c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "Backlog 35", + "url": "https://github.com/Galaticos-API/API-1/blob/1edd3096e46cb1cb9c794dbaec887a83487c0e97/readme.md#L74" + } + }, + { + "table": "projeto", + "values": { + "id": "60000000-0000-4000-8000-000000000006", + "nome": "PRE06 — Acervo API-2", + "cliente": "Organização não identificada", + "descricao": "Recorte documental curado do projeto API-2; não é cópia integral nem avaliação de pessoas.", + "status": "ativo" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-2", + "revision": "e568684bc66a8a339a04a1f091d9599754d21cf6", + "path": "DOCS/Documentação das Sprints/DocSprint1.md", + "source_sha256": "b64e0422210a7799af4519a3a0d21406920ef46169a1b3424888544ba584150c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "US-01", + "url": "https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L43" + } + }, + { + "table": "documento", + "values": { + "id": "60000000-0000-4000-8000-000000000007", + "projeto_id": "60000000-0000-4000-8000-000000000006", + "nome": "API-2 — Administrar acesso de usuários", + "mime": "text/markdown", + "caminho": "database/seed/curated/api-2-us-01.md", + "status_processamento": "pendente" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-2", + "revision": "e568684bc66a8a339a04a1f091d9599754d21cf6", + "path": "DOCS/Documentação das Sprints/DocSprint1.md", + "source_sha256": "b64e0422210a7799af4519a3a0d21406920ef46169a1b3424888544ba584150c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "US-01", + "url": "https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L43" + } + }, + { + "table": "chunk", + "values": { + "id": "60000000-0000-4000-8000-000000000008", + "projeto_id": "60000000-0000-4000-8000-000000000006", + "entidade_tipo": "documento", + "entidade_id": "60000000-0000-4000-8000-000000000007", + "texto": "A documentação da primeira sprint descreve cadastro, consulta, edição e inativação de usuários pelo RH para administrar o acesso à plataforma.", + "metadados_json": { + "dataset": "pre06-historical-v1", + "source_url": "https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L43", + "source_revision": "e568684bc66a8a339a04a1f091d9599754d21cf6", + "source_sha256": "b64e0422210a7799af4519a3a0d21406920ef46169a1b3424888544ba584150c", + "classification": "curated-public-documentation", + "embedding_status": "pending", + "individual_experience": "not_evidenced" + } + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-2", + "revision": "e568684bc66a8a339a04a1f091d9599754d21cf6", + "path": "DOCS/Documentação das Sprints/DocSprint1.md", + "source_sha256": "b64e0422210a7799af4519a3a0d21406920ef46169a1b3424888544ba584150c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "US-01", + "url": "https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L43" + } + }, + { + "table": "documento", + "values": { + "id": "60000000-0000-4000-8000-000000000009", + "projeto_id": "60000000-0000-4000-8000-000000000006", + "nome": "API-2 — Registrar plano individual por ano", + "mime": "text/markdown", + "caminho": "database/seed/curated/api-2-us-02.md", + "status_processamento": "pendente" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-2", + "revision": "e568684bc66a8a339a04a1f091d9599754d21cf6", + "path": "DOCS/Documentação das Sprints/DocSprint1.md", + "source_sha256": "b64e0422210a7799af4519a3a0d21406920ef46169a1b3424888544ba584150c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "US-02", + "url": "https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L44" + } + }, + { + "table": "chunk", + "values": { + "id": "60000000-0000-4000-8000-000000000010", + "projeto_id": "60000000-0000-4000-8000-000000000006", + "entidade_tipo": "documento", + "entidade_id": "60000000-0000-4000-8000-000000000009", + "texto": "A documentação descreve criação de um plano de desenvolvimento individual associado a um colaborador e a um ano, preservando o histórico de planos.", + "metadados_json": { + "dataset": "pre06-historical-v1", + "source_url": "https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L44", + "source_revision": "e568684bc66a8a339a04a1f091d9599754d21cf6", + "source_sha256": "b64e0422210a7799af4519a3a0d21406920ef46169a1b3424888544ba584150c", + "classification": "curated-public-documentation", + "embedding_status": "pending", + "individual_experience": "not_evidenced" + } + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-2", + "revision": "e568684bc66a8a339a04a1f091d9599754d21cf6", + "path": "DOCS/Documentação das Sprints/DocSprint1.md", + "source_sha256": "b64e0422210a7799af4519a3a0d21406920ef46169a1b3424888544ba584150c", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "US-02", + "url": "https://github.com/Galaticos-API/API-2/blob/e568684bc66a8a339a04a1f091d9599754d21cf6/DOCS/Documenta%C3%A7%C3%A3o%20das%20Sprints/DocSprint1.md#L44" + } + }, + { + "table": "projeto", + "values": { + "id": "60000000-0000-4000-8000-000000000011", + "nome": "PRE06 — Acervo API-3", + "cliente": "Organização não identificada", + "descricao": "Recorte documental curado do projeto API-3; não é cópia integral nem avaliação de pessoas.", + "status": "ativo" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-3", + "revision": "34f1cc21825f9c392dcd776d6567fba2288b2e81", + "path": "DOCS/analise_backend/analiseRequisitosBackend.md", + "source_sha256": "a608ea5aa562682ae2c236ede3eca07b092622602c03928a726347ffe5c1cf9b", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "GRF-01", + "url": "https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L6" + } + }, + { + "table": "documento", + "values": { + "id": "60000000-0000-4000-8000-000000000012", + "projeto_id": "60000000-0000-4000-8000-000000000011", + "nome": "API-3 — Visualizar saldo de crédito nacional", + "mime": "text/markdown", + "caminho": "database/seed/curated/api-3-grf-01.md", + "status_processamento": "pendente" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-3", + "revision": "34f1cc21825f9c392dcd776d6567fba2288b2e81", + "path": "DOCS/analise_backend/analiseRequisitosBackend.md", + "source_sha256": "a608ea5aa562682ae2c236ede3eca07b092622602c03928a726347ffe5c1cf9b", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "GRF-01", + "url": "https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L6" + } + }, + { + "table": "chunk", + "values": { + "id": "60000000-0000-4000-8000-000000000013", + "projeto_id": "60000000-0000-4000-8000-000000000011", + "entidade_tipo": "documento", + "entidade_id": "60000000-0000-4000-8000-000000000012", + "texto": "A análise de requisitos prevê gráfico de linha do saldo nacional de crédito, usando as séries 20539, 20540 e 20541.", + "metadados_json": { + "dataset": "pre06-historical-v1", + "source_url": "https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L6", + "source_revision": "34f1cc21825f9c392dcd776d6567fba2288b2e81", + "source_sha256": "a608ea5aa562682ae2c236ede3eca07b092622602c03928a726347ffe5c1cf9b", + "classification": "curated-public-documentation", + "embedding_status": "pending", + "individual_experience": "not_evidenced" + } + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-3", + "revision": "34f1cc21825f9c392dcd776d6567fba2288b2e81", + "path": "DOCS/analise_backend/analiseRequisitosBackend.md", + "source_sha256": "a608ea5aa562682ae2c236ede3eca07b092622602c03928a726347ffe5c1cf9b", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "GRF-01", + "url": "https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L6" + } + }, + { + "table": "documento", + "values": { + "id": "60000000-0000-4000-8000-000000000014", + "projeto_id": "60000000-0000-4000-8000-000000000011", + "nome": "API-3 — Comparar oportunidades por estado", + "mime": "text/markdown", + "caminho": "database/seed/curated/api-3-grf-08.md", + "status_processamento": "pendente" + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-3", + "revision": "34f1cc21825f9c392dcd776d6567fba2288b2e81", + "path": "DOCS/analise_backend/analiseRequisitosBackend.md", + "source_sha256": "a608ea5aa562682ae2c236ede3eca07b092622602c03928a726347ffe5c1cf9b", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "GRF-08", + "url": "https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L13" + } + }, + { + "table": "chunk", + "values": { + "id": "60000000-0000-4000-8000-000000000015", + "projeto_id": "60000000-0000-4000-8000-000000000011", + "entidade_tipo": "documento", + "entidade_id": "60000000-0000-4000-8000-000000000014", + "texto": "A análise de requisitos prevê gráfico de barras do índice de oportunidade, com pontuação entre zero e dez e ordenação por estado.", + "metadados_json": { + "dataset": "pre06-historical-v1", + "source_url": "https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L13", + "source_revision": "34f1cc21825f9c392dcd776d6567fba2288b2e81", + "source_sha256": "a608ea5aa562682ae2c236ede3eca07b092622602c03928a726347ffe5c1cf9b", + "classification": "curated-public-documentation", + "embedding_status": "pending", + "individual_experience": "not_evidenced" + } + }, + "source": { + "repository": "https://github.com/Galaticos-API/API-3", + "revision": "34f1cc21825f9c392dcd776d6567fba2288b2e81", + "path": "DOCS/analise_backend/analiseRequisitosBackend.md", + "source_sha256": "a608ea5aa562682ae2c236ede3eca07b092622602c03928a726347ffe5c1cf9b", + "classification": "curated-public-documentation", + "transformation": "Resumo em português; dados pessoais, autores, contatos, clientes e anexos excluídos.", + "source_kind": "historical", + "locator": "GRF-08", + "url": "https://github.com/Galaticos-API/API-3/blob/34f1cc21825f9c392dcd776d6567fba2288b2e81/DOCS/analise_backend/analiseRequisitosBackend.md#L13" + } + } + ] +} diff --git a/database/seed/validation-cases.json b/database/seed/validation-cases.json new file mode 100644 index 0000000..7c0b801 --- /dev/null +++ b/database/seed/validation-cases.json @@ -0,0 +1,11 @@ +{ + "dataset": "pre06-historical-v1", + "status": "expectativas de conteúdo; motor de busca e embeddings não validados", + "cases": [ + { "query": "Como restringir o acesso administrativo?", "project": "API-1", "expected_source": "Backlog 23", "purpose": "PBI-02.3.1" }, + { "query": "Como administrar acesso de usuários?", "project": "API-2", "expected_source": "US-01", "purpose": "PBI-02.3.1" }, + { "query": "Existe histórico de planos por ano?", "project": "API-2", "expected_source": "US-02", "purpose": "PBI-02.3.1" }, + { "query": "Como apresentar métricas em gráficos?", "projects": ["API-1", "API-3"], "candidate_sources": ["Backlog 35", "GRF-01", "GRF-08"], "purpose": "PBI-03.1.4; candidatos documentais, sem afirmar equivalência funcional" }, + { "query": "Quem implementou os gráficos?", "expected": "Não há evidência de experiência individual neste recorte.", "purpose": "PBI-05.2.1; cenário negativo" } + ] +}