feat(device-manager): add control and audit workspaces

This commit is contained in:
Codex
2026-08-13 11:37:36 +03:00
parent 4116f5ba95
commit 1c5246afe8
10 changed files with 1769 additions and 24 deletions
@@ -13,6 +13,7 @@ const actor = Object.freeze({
groupRefs: ["group:device-engineers"],
ownerScopes: [{ scopeKind: "personal", ownerRef: "user:device-admin" }],
});
const platformActor = Object.freeze({ ...actor, hubRole: "owner" });
test("Device Core client creates trusted actor headers and keeps its token server-side", async () => {
const calls = [];
@@ -87,11 +88,83 @@ test("local preview is empty and creates resources only through canonical comman
description: null,
});
const adapterPackage = await client.execute("adapter-packages:ensure", platformActor, {
packageKey: "generic-tracker",
displayName: "Generic tracker",
publisherRef: "publisher:nodedc",
lifecycleState: "active",
});
const adapterVersion = await client.execute("adapter-versions:register", platformActor, {
adapterPackageRef: adapterPackage.result.adapterPackage.adapterPackageRef,
version: "1.0.0",
runtimePackageRef: "artifact:generic-tracker:1.0.0",
contentDigest: `sha256:${"a".repeat(64)}`,
contractVersion: "device-adapter.v1",
capabilities: ["telemetry"],
lifecycleState: "draft",
});
const modelProfile = await client.execute("model-profiles:register", platformActor, {
adapterVersionRef: adapterVersion.result.adapterVersion.adapterVersionRef,
profileRef: "generic.tracker.v1",
schemaVersion: "1.0.0",
vendor: "Generic",
model: "Tracker",
deviceType: "tracker",
protocol: "INTERNAL",
schemaArtifactRef: "schema:generic.tracker.v1",
profileDigest: `sha256:${"b".repeat(64)}`,
capabilities: ["telemetry"],
lifecycleState: "draft",
});
const edge = await client.execute("edges:ensure", platformActor, {
edgeKey: "preview-edge",
displayName: "Preview Edge",
deploymentRef: "deployment:preview-edge",
lifecycleState: "provisioning",
});
await client.execute("routes:ensure", actor, {
projectRef,
routeKey: "preview-route",
displayName: "Preview route",
edgeRef: edge.result.edge.edgeRef,
modelProfileRef: modelProfile.result.modelProfile.modelProfileRef,
listenerRef: "listener:preview",
protocol: "INTERNAL",
direction: "telemetry",
lifecycleState: "draft",
});
const collectionRef = (await client.getWorkspace(actor, projectRef))
.collections[0].collectionRef;
await client.execute("device-bindings:ensure", actor, {
projectRef,
bindingKey: "preview-binding",
displayName: "Preview binding",
source: { kind: "collection", ref: collectionRef },
targetKind: "foundry.application",
targetRef: "application:preview-map",
capabilities: ["observe"],
});
await client.execute("project-grants:upsert", actor, {
projectRef,
principalKind: "group",
principalRef: "group:preview-viewers",
projectRole: "viewer",
capabilityAllow: [],
capabilityDeny: [],
lifecycleState: "active",
});
const projects = await client.listProjects(actor);
assert.equal(projects.length, 1);
assert.equal(projects[0].counts.collections, 1);
const workspace = await client.getWorkspace(actor, projectRef);
assert.equal(workspace.collections[0].collectionKey, "field-devices");
assert.equal(workspace.adapterPackages[0].packageKey, "generic-tracker");
assert.equal(workspace.routes[0].routeKey, "preview-route");
assert.equal(workspace.bindings[0].lifecycleState, "pending_external_approval");
assert.equal(workspace.grants.length, 2);
assert.ok(workspace.auditEvents.some((event) => event.eventType === "device_binding.created"));
assert.equal(workspace.policies.commandTransport, "disabled");
assert.deepEqual(workspace.devices, []);
});