feat: complete TASK-WP0-01 toolchain skeleton

This commit is contained in:
suyx
2026-07-27 17:13:01 +08:00
parent 67e7a17d96
commit ae20eaf01f
39 changed files with 3588 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
import { describe, expect, it } from "vitest";
import { createApp } from "../../apps/api/src/app.js";
describe("Fastify skeleton", () => {
it("becomes ready without adding a product route", async () => {
const app = createApp();
await app.ready();
expect(app.printRoutes()).not.toContain("health");
await app.close();
});
});
+15
View File
@@ -0,0 +1,15 @@
import { createRequire } from "node:module";
import { describe, expect, it } from "vitest";
const requireFromApi = createRequire(new URL("../../apps/api/package.json", import.meta.url));
const Database = requireFromApi("better-sqlite3");
describe("better-sqlite3 native module", () => {
it("executes an in-memory query without creating business data", () => {
const database = new Database(":memory:");
const row = database.prepare("select 1 as value").get();
database.close();
expect(row.value).toBe(1);
});
});
+59
View File
@@ -0,0 +1,59 @@
import assert from "node:assert/strict";
import { existsSync, readFileSync } from "node:fs";
import test from "node:test";
import { frozenPackages } from "../../scripts/frozen-versions.mjs";
const expectedFiles = [
"NuGet.Config",
"pnpm-lock.yaml",
"pnpm-workspace.yaml",
"tsconfig.base.json",
"apps/web/package.json",
"apps/web/src/toolchain-probe.tsx",
"apps/api/package.json",
"apps/api/src/app.ts",
"apps/worker/package.json",
"apps/worker/src/worker.ts",
"packages/shared-contracts/package.json",
"packages/shared-contracts/src/index.ts",
"scripts/validate-tdd-trace.mjs",
"scripts/native-smoke.mjs",
"supervisor/Dada.Supervisor/Dada.Supervisor.csproj",
];
function readJson(path) {
return JSON.parse(readFileSync(path, "utf8"));
}
test("TASK-WP0-01 has no unresolved task dependency", () => {
const manifest = readJson("tasks.manifest.json");
const task = manifest.tasks.find((item) => item.task_id === "TASK-WP0-01");
assert.ok(task, "TASK-WP0-01 must exist in tasks.manifest.json");
assert.deepEqual(task.dependencies.task_ids, []);
assert.deepEqual(task.dependencies.work_packages, []);
assert.equal(task.dependencies.source_text, "无");
});
test("TDD-WP0-DEP-001 frozen toolchain contract is implemented", () => {
const problems = [];
for (const path of expectedFiles) {
if (!existsSync(path)) problems.push(`missing file: ${path}`);
}
for (const [path, sections] of Object.entries(frozenPackages)) {
if (!existsSync(path)) continue;
const packageJson = readJson(path);
for (const [section, packages] of Object.entries(sections)) {
for (const [name, version] of Object.entries(packages)) {
const actual = packageJson[section]?.[name];
if (actual !== version) {
problems.push(`${path} ${section}.${name}: expected ${version}, got ${actual ?? "missing"}`);
}
}
}
}
assert.deepEqual(problems, []);
});
+57
View File
@@ -0,0 +1,57 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
import { createApp } from "../../apps/api/src/app.js";
import { renderToolchainProbe } from "../../apps/web/src/toolchain-probe.js";
import { validateTddTrace } from "../../scripts/lib/tdd-trace.mjs";
function readManifest() {
return JSON.parse(readFileSync(new URL("../../tasks.manifest.json", import.meta.url), "utf8"));
}
describe("TASK-WP0-01 minimum toolchain", () => {
it("renders through React and Fabric at the frozen versions", () => {
const probe = renderToolchainProbe();
expect(probe.reactMarkup).toContain("Dada toolchain probe");
expect(probe.fabricSvg).toContain("<rect");
expect(probe.fabricVersion).toBe("7.4.0");
});
it("loads and closes Fastify with the frozen Swagger plugin", async () => {
const app = createApp();
await app.ready();
expect(app.hasPlugin("@fastify/swagger")).toBe(true);
await app.close();
});
it("validates the frozen TDD trace", () => {
const result = validateTddTrace();
expect(result.errors).toEqual([]);
expect(result.summary).toMatchObject({
acceptanceCriteria: 52,
parentFamilies: 89,
requirements: 109,
tasks: 52,
testCases: 117,
uiPages: 22,
});
});
it("rejects a missing normative case", () => {
const manifest = readManifest();
manifest.case_catalog.pop();
const result = validateTddTrace({ manifestOverride: manifest });
expect(result.status).toBe("failed");
expect(result.errors.some((error) => error.includes("normative case count"))).toBe(true);
});
it("rejects a duplicated case assignment", () => {
const manifest = readManifest();
manifest.tasks[1].case_ids.push(manifest.tasks[0].case_ids[0]);
const result = validateTddTrace({ manifestOverride: manifest });
expect(result.status).toBe("failed");
expect(result.errors.some((error) => error.includes("duplicate case assignment"))).toBe(true);
});
});