feat(device-core): add device registry schema
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
|
||||
const migrationUrl = new URL(
|
||||
"../migrations/004_device_registry_foundation.sql",
|
||||
import.meta.url,
|
||||
);
|
||||
const repositoryUrl = new URL("../src/postgres-repository.mjs", import.meta.url);
|
||||
|
||||
test("registry migration defines generic catalog, edge and runtime boundaries", async () => {
|
||||
const sql = await readFile(migrationUrl, "utf8");
|
||||
|
||||
for (const table of [
|
||||
"device_adapter_packages",
|
||||
"device_adapter_versions",
|
||||
"device_edges",
|
||||
"device_routes",
|
||||
"device_sessions",
|
||||
"device_enrollment_intents",
|
||||
]) {
|
||||
assert.match(sql, new RegExp(`create table if not exists ${table}`));
|
||||
}
|
||||
assert.match(sql, /add column if not exists adapter_version_id uuid/);
|
||||
assert.match(sql, /content_digest ~ '\^sha256:\[a-f0-9\]\{64\}\$'/);
|
||||
assert.match(sql, /expected_identifier_digest ~ '\^hmac-sha256:\[a-f0-9\]\{64\}\$'/);
|
||||
});
|
||||
|
||||
test("registry migration enforces project, route, edge and device isolation", async () => {
|
||||
const sql = await readFile(migrationUrl, "utf8");
|
||||
|
||||
assert.match(
|
||||
sql,
|
||||
/foreign key \(route_id, edge_id, project_id\)\s+references device_routes\(id, edge_id, project_id\)/,
|
||||
);
|
||||
assert.match(
|
||||
sql,
|
||||
/foreign key \(route_id, project_id, model_profile_ref\)\s+references device_routes\(id, project_id, model_profile_ref\)/,
|
||||
);
|
||||
assert.match(
|
||||
sql,
|
||||
/foreign key \(device_id, project_id\)\s+references device_instances\(id, project_id\)/,
|
||||
);
|
||||
assert.match(
|
||||
sql,
|
||||
/foreign key \(claimed_device_id, project_id\)\s+references device_instances\(id, project_id\)/,
|
||||
);
|
||||
});
|
||||
|
||||
test("registry migration stores no device, tenant, network or credential seed", async () => {
|
||||
const sql = await readFile(migrationUrl, "utf8");
|
||||
|
||||
assert.doesNotMatch(sql, /insert\s+into/i);
|
||||
assert.doesNotMatch(sql, /dcctouch|arusnavi|\bb2\b|imei|gelios/i);
|
||||
assert.doesNotMatch(sql, /155\.212\.|device\.nodedc\.ru|synology/i);
|
||||
assert.doesNotMatch(sql, /password|secret|private_key|credential_ref/i);
|
||||
});
|
||||
|
||||
test("repository applies registry migration after management receipts", async () => {
|
||||
const source = await readFile(repositoryUrl, "utf8");
|
||||
const managementIndex = source.indexOf("003_device_management_commands.sql");
|
||||
const registryIndex = source.indexOf("004_device_registry_foundation.sql");
|
||||
|
||||
assert.notEqual(managementIndex, -1);
|
||||
assert.notEqual(registryIndex, -1);
|
||||
assert.ok(managementIndex < registryIndex);
|
||||
});
|
||||
Reference in New Issue
Block a user