feat: establish NekoNest Cloud control and relay
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import {
|
||||
CONTROL_PLANE_EXCLUSIONS,
|
||||
DATA_INVENTORY,
|
||||
INVENTORIED_TABLES,
|
||||
} from "../app/privacy/data-inventory.ts";
|
||||
|
||||
test("keeps the public data inventory complete against the D1 schema", async () => {
|
||||
const schema = await readFile(new URL("../db/schema.ts", import.meta.url), "utf8");
|
||||
const schemaTables = [...schema.matchAll(/sqliteTable\(\s*["']([^"']+)["']/g)]
|
||||
.map((match) => match[1])
|
||||
.sort();
|
||||
const inventoryTables = [...INVENTORIED_TABLES].sort();
|
||||
|
||||
assert.equal(new Set(schemaTables).size, schemaTables.length, "schema table names must be unique");
|
||||
assert.equal(new Set(inventoryTables).size, inventoryTables.length, "inventory table names must be unique");
|
||||
assert.deepEqual(inventoryTables, schemaTables);
|
||||
});
|
||||
|
||||
test("publishes purpose, retention boundary, and user control for every data group", () => {
|
||||
assert.ok(DATA_INVENTORY.length >= 7);
|
||||
for (const group of DATA_INVENTORY) {
|
||||
assert.ok(group.summary.length > 10, `${group.id} needs a summary`);
|
||||
assert.ok(group.purpose.length > 10, `${group.id} needs a purpose`);
|
||||
assert.ok(group.retention.length > 10, `${group.id} needs a retention boundary`);
|
||||
assert.ok(group.userControl.length > 10, `${group.id} needs a user control statement`);
|
||||
assert.ok(group.examples.length > 0, `${group.id} needs examples`);
|
||||
assert.ok(group.tables.length > 0, `${group.id} needs table coverage`);
|
||||
}
|
||||
|
||||
const dormant = DATA_INVENTORY.find((group) => group.id === "dormant-billing");
|
||||
assert.equal(dormant?.status, "dormant");
|
||||
assert.match(dormant?.purpose ?? "", /服务端拒绝写入/);
|
||||
assert.ok(CONTROL_PLANE_EXCLUSIONS.some((entry) => entry.item === "项目文件和任意磁盘目录内容"));
|
||||
assert.match(
|
||||
CONTROL_PLANE_EXCLUSIONS.find((entry) => entry.item.includes("明文配对码"))?.boundary ?? "",
|
||||
/短暂处理,不持久化到 D1/,
|
||||
);
|
||||
});
|
||||
|
||||
test("keeps the public privacy page honest about unfinished deletion and compliance work", async () => {
|
||||
const [page, shell, readiness, docs, plan] = await Promise.all([
|
||||
readFile(new URL("../app/privacy/page.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/components/Shells.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/readiness/page.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../docs/data-inventory.md", import.meta.url), "utf8"),
|
||||
readFile(new URL("../docs/implementation-plan.md", import.meta.url), "utf8"),
|
||||
]);
|
||||
|
||||
assert.match(page, /这不是一份拿模板拼出的最终隐私政策/);
|
||||
assert.match(page, /隐私门禁还没有通过/);
|
||||
assert.match(page, /不会宣称“已经合规”/);
|
||||
assert.match(page, /DATA_INVENTORY\.map/);
|
||||
assert.match(shell, /href="\/privacy"/);
|
||||
assert.match(readiness, /查看公测数据说明/);
|
||||
assert.match(docs, /以上项目完成前.*P0 门禁继续保持阻止/);
|
||||
assert.match(plan, /\[x\].*D1 schema 完整对齐的控制平面数据清单/);
|
||||
assert.doesNotMatch(`${page}\n${docs}`, /隐私门禁已经通过|已经完成合规/);
|
||||
});
|
||||
|
||||
test("documents retention facts that are enforced by the current pairing code", async () => {
|
||||
const repository = await readFile(new URL("../db/repository.ts", import.meta.url), "utf8");
|
||||
assert.match(repository, /const expiresAt = isoAfterMinutes\(10\)/);
|
||||
assert.match(repository, /pairing_claim_rate_limits WHERE window_start < \?/);
|
||||
assert.match(repository, /nowMilliseconds - 24 \* 60 \* 60_000/);
|
||||
assert.match(repository, /pairing_claim_attempts WHERE created_at < \?/);
|
||||
assert.match(repository, /nowMilliseconds - 30 \* 24 \* 60 \* 60_000/);
|
||||
});
|
||||
Reference in New Issue
Block a user