扩展 AI 公司目录覆盖并保留逐条核查台账
Verify and deploy Tabularium / verify-and-deploy (pull_request) Successful in 11m10s

This commit is contained in:
2026-10-30 04:31:33 +08:00
parent 3e2183798d
commit d50281a1e9
8 changed files with 49662 additions and 21 deletions
+29 -4
View File
@@ -4,6 +4,7 @@ import { mkdtempSync, rmSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import seed from "../../../content/research/ai-companies.seed.json";
import coverageAudit from "../../../content/research/ai-companies.coverage.json";
import { readResearchSnapshot } from "../src/lib/ai-research-store";
import { openSiteDatabase } from "../src/lib/site-database";
import { categorySummary, evidenceUrl, validateResearch, type ResearchSnapshot } from "../src/lib/ai-research";
@@ -20,8 +21,8 @@ test("research revisions share the authentication database and preserve replay l
for (let i = 0; i < 20; i++) consumeCode(config, "invalid");
assert.equal(consumeCode(config, "invalid"), "limited");
const initial = readResearchSnapshot();
assert.equal(initial.companies.length, 58);
assert.equal(initial.evidence.length, 100);
assert.equal(initial.companies.length, 986);
assert.equal(initial.evidence.length, 1035);
assert.equal(initial.observations.length, 75);
assert.deepEqual(readResearchSnapshot(), initial, "reopening does not duplicate records");
const db = openSiteDatabase();
@@ -60,10 +61,10 @@ test("research validation rejects broken evidence and unsafe source links", () =
test("disclosure counts exclude client income, biographies, targets and duplicate milestones", () => {
const snapshot = seed as ResearchSnapshot;
const summary = categorySummary(snapshot);
assert.equal(summary.reduce((n, c) => n + c.count, 0), 58);
assert.equal(summary.reduce((n, c) => n + c.count, 0), 986);
assert.equal(summary.reduce((n, c) => n + c.self, 0), 8);
assert.equal(summary.reduce((n, c) => n + c.estimate, 0), 1);
assert.equal(summary.reduce((n, c) => n + c.unknown, 0), 49);
assert.equal(summary.reduce((n, c) => n + c.unknown, 0), 977);
assert.equal(snapshot.companies.find((c) => c.name === "Rork")?.revenueStatus, "unknown");
assert.equal(snapshot.companies.find((c) => c.name === "Result")?.revenueStatus, "unknown");
assert.ok(snapshot.observations.filter((o) => o.selection === "signal").every((o) => o.scope === "公司整体"));
@@ -85,3 +86,27 @@ test("retracted ARR and projected margins remain excluded", () => {
assert.equal(snapshot.observations.filter((o) => o.company === peec.id && o.selection === "signal").length, 1);
assert.ok(snapshot.observations.some((o) => o.company === peec.id && o.selection === "historical-estimate"));
});
test("directory coverage reconciles every candidate and keeps profile-only income unknown", () => {
const snapshot = seed as ResearchSnapshot;
const coverage = snapshot.coverage!;
assert.equal(coverageAudit.records.length, coverage.candidateRecords);
assert.equal(new Set(coverageAudit.records.map((r) => r.ycId)).size, coverage.candidateRecords);
const count = (status: string) => coverageAudit.records.filter((r) => r.status === status).length;
assert.equal(count("imported"), coverage.newProfiles);
assert.equal(count("existing"), coverage.existingProfiles);
assert.equal(count("date-conflict"), coverage.dateConflicts);
assert.equal(count("year-outside-or-missing"), coverage.otherOrMissingYear);
assert.equal(count("ai-unclear"), coverage.unclearAI);
for (const row of coverageAudit.records.filter((r) => r.status === "imported")) {
const company = snapshot.companies.find((c) => c.id === `YC${row.ycId}`)!;
assert.ok(company.profileOnly);
assert.equal(company.url, row.source);
assert.equal(company.revenueStatus, "unknown");
assert.equal(company.year, row.foundedYear);
assert.ok([2025, 2026].includes(company.year!));
}
const invalid = structuredClone(snapshot);
invalid.coverage!.newProfiles += 1;
assert.throws(() => validateResearch(invalid), /coverage accounting/);
});