feat(device-manager): add full device profile workspace
This commit is contained in:
@@ -80,7 +80,7 @@ export function createDeviceCoreClient({ baseUrl, token, fetchImpl = fetch } = {
|
||||
};
|
||||
}
|
||||
|
||||
export function createLocalPreviewDeviceCore() {
|
||||
export function createLocalPreviewDeviceCore({ fixture = null } = {}) {
|
||||
const ownerScopes = new Map();
|
||||
const projects = new Map();
|
||||
const collections = new Map();
|
||||
@@ -90,6 +90,8 @@ export function createLocalPreviewDeviceCore() {
|
||||
const edges = new Map();
|
||||
const routes = new Map();
|
||||
const enrollments = new Map();
|
||||
const devices = new Map();
|
||||
const sessions = new Map();
|
||||
const bindings = new Map();
|
||||
const grants = new Map();
|
||||
const configurationRevisions = new Map();
|
||||
@@ -121,7 +123,11 @@ export function createLocalPreviewDeviceCore() {
|
||||
.filter((collection) => collection.projectRef === project.projectRef);
|
||||
return {
|
||||
...project,
|
||||
counts: { devices: 0, collections: projectCollections.length, discoveries: 0 },
|
||||
counts: {
|
||||
devices: projectValues(devices, project.projectRef).length,
|
||||
collections: projectCollections.length,
|
||||
discoveries: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -130,7 +136,8 @@ export function createLocalPreviewDeviceCore() {
|
||||
if (!project) throw serviceError("device_project_not_found", 404);
|
||||
return {
|
||||
project: projectSummary(project),
|
||||
devices: [],
|
||||
devices: projectValues(devices, projectRef)
|
||||
.map(({ projectRef: _projectRef, ...device }) => device),
|
||||
discoveries: [],
|
||||
enrollments: projectValues(enrollments, projectRef),
|
||||
collections: projectValues(collections, projectRef)
|
||||
@@ -140,7 +147,8 @@ export function createLocalPreviewDeviceCore() {
|
||||
modelProfiles: [...modelProfiles.values()],
|
||||
edges: [...edges.values()],
|
||||
routes: projectValues(routes, projectRef),
|
||||
sessions: [],
|
||||
sessions: projectValues(sessions, projectRef)
|
||||
.map(({ projectRef: _projectRef, ...session }) => session),
|
||||
bindings: projectValues(bindings, projectRef),
|
||||
configurationRevisions: projectValues(configurationRevisions, projectRef),
|
||||
configurationStates: projectValues(configurationStates, projectRef),
|
||||
@@ -156,6 +164,20 @@ export function createLocalPreviewDeviceCore() {
|
||||
};
|
||||
}
|
||||
|
||||
if (fixture === "arusnavi-b2") seedArusnaviB2Preview({
|
||||
ownerScopes,
|
||||
projects,
|
||||
devices,
|
||||
modelProfiles,
|
||||
edges,
|
||||
routes,
|
||||
sessions,
|
||||
configurationStates,
|
||||
});
|
||||
else if (fixture != null && fixture !== "") {
|
||||
throw serviceError("device_manager_preview_fixture_invalid", 400);
|
||||
}
|
||||
|
||||
return {
|
||||
configured: true,
|
||||
async listProjects() {
|
||||
@@ -552,6 +574,8 @@ export function createLocalPreviewDeviceCore() {
|
||||
edges,
|
||||
routes,
|
||||
enrollments,
|
||||
devices,
|
||||
sessions,
|
||||
bindings,
|
||||
grants,
|
||||
configurationRevisions,
|
||||
@@ -572,6 +596,160 @@ function requirePlatformOwner(actor) {
|
||||
}
|
||||
}
|
||||
|
||||
function seedArusnaviB2Preview({
|
||||
ownerScopes,
|
||||
projects,
|
||||
devices,
|
||||
modelProfiles,
|
||||
edges,
|
||||
routes,
|
||||
sessions,
|
||||
configurationStates,
|
||||
}) {
|
||||
const timestamp = new Date().toISOString();
|
||||
const ownerScopeRef = "owner-scope:78da71d5-f48f-4de0-8e47-729f6d644151";
|
||||
const projectRef = "project:ad7b357c-c7ac-4bf8-a638-c7f956e9aa71";
|
||||
const deviceRef = "device:b6a55921-7888-44b5-a93e-241aa2fdd3d7";
|
||||
const edgeRef = "edge:73da0c42-a641-4559-b8f7-23509b60bfe9";
|
||||
const routeRef = "route:fef9b7a0-a462-4d68-9991-af026203368b";
|
||||
const sessionRef = "session:57ead610-47de-45f7-a42d-fbe4fa0aba38";
|
||||
const scope = {
|
||||
ownerScopeRef,
|
||||
scopeKind: "personal",
|
||||
ownerRef: "user:local-device-admin",
|
||||
displayName: "Local Device Admin",
|
||||
lifecycleState: "active",
|
||||
};
|
||||
ownerScopes.set("personal:user:local-device-admin", scope);
|
||||
projects.set(projectRef, {
|
||||
projectRef,
|
||||
projectKey: "arusnavi-b2-preview",
|
||||
name: "ARUSNAVI B2 preview",
|
||||
description: "Локальная визуальная фикстура без реальных идентификаторов и команд",
|
||||
lifecycleState: "active",
|
||||
ownerScope: scope,
|
||||
access: { projectRole: "owner", capabilities: ownerCapabilities },
|
||||
counts: { devices: 1, collections: 0, discoveries: 0 },
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
});
|
||||
modelProfiles.set("arusnavi.b2.internal.v1", {
|
||||
modelProfileRef: "arusnavi.b2.internal.v1",
|
||||
adapterVersionRef: null,
|
||||
schemaVersion: "1.0.0",
|
||||
vendor: "ARUSNAVI",
|
||||
model: "B2",
|
||||
deviceType: "tracker",
|
||||
protocol: "INTERNAL",
|
||||
schemaArtifactRef: "schema:arusnavi.b2.internal.v1",
|
||||
profileDigest: null,
|
||||
capabilities: ["telemetry", "configuration", "commands"],
|
||||
lifecycleState: "active",
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
});
|
||||
edges.set(edgeRef, {
|
||||
edgeRef,
|
||||
edgeKey: "preview-edge",
|
||||
displayName: "Preview VPS edge",
|
||||
deploymentRef: "deployment:preview",
|
||||
lifecycleState: "active",
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
});
|
||||
routes.set(routeRef, {
|
||||
routeRef,
|
||||
projectRef,
|
||||
routeKey: "preview-b2-route",
|
||||
displayName: "B2 direct preview",
|
||||
edgeRef,
|
||||
edgeName: "Preview VPS edge",
|
||||
modelProfileRef: "arusnavi.b2.internal.v1",
|
||||
profileName: "ARUSNAVI B2",
|
||||
listenerRef: "listener:preview",
|
||||
protocol: "INTERNAL",
|
||||
direction: "bidirectional",
|
||||
lifecycleState: "active",
|
||||
sessionCount: 1,
|
||||
activeSessionCount: 1,
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
});
|
||||
devices.set(deviceRef, {
|
||||
projectRef,
|
||||
deviceRef,
|
||||
deviceKey: "pilot-b2-preview",
|
||||
displayName: "Пилотный B2",
|
||||
modelProfileRef: "arusnavi.b2.internal.v1",
|
||||
lifecycleState: "active",
|
||||
identifier: { kind: "imei", masked: "***********0001" },
|
||||
session: { state: "online", lastSeenAt: timestamp },
|
||||
reported: {
|
||||
observedAt: timestamp,
|
||||
identity: { iccid1: "****************1111", iccid2: "****************2222" },
|
||||
firmware: { currentVersion: "0.02", appliedAt: timestamp, availableVersion: "0.05" },
|
||||
configuration: {
|
||||
monitoring: {
|
||||
servers: [
|
||||
{ host: "legacy.example.invalid", port: 20623, protocol: "INTERNAL", identity: "0" },
|
||||
{ host: "direct.example.invalid", port: 9921, protocol: "INTERNAL", identity: "0" },
|
||||
],
|
||||
},
|
||||
transmission: { navigation: { position: true, motion: true, hdop: false } },
|
||||
trajectory: {
|
||||
normal: { courseDeltaDegrees: 15, speedDeltaKph: 10, distanceMeters: 15, parkingIntervalSeconds: 15 },
|
||||
roaming: { courseDeltaDegrees: 20, speedDeltaKph: 50, distanceMeters: 1000, parkingIntervalSeconds: 300 },
|
||||
},
|
||||
navigation: {
|
||||
sources: { satellite: true, wifi: false, lbs: false, tag: false },
|
||||
constellations: { gps: true, glonass: true, galileo: false, beidou: false },
|
||||
filter: { minimumSatellites: 4, maximumHdopTimesTen: 30 },
|
||||
},
|
||||
},
|
||||
telemetry: {
|
||||
navigation: {
|
||||
latitude: "55.7500",
|
||||
longitude: "37.6200",
|
||||
speedKph: 18,
|
||||
altitudeMeters: 156,
|
||||
satellites: 12,
|
||||
courseDegrees: 84,
|
||||
hdop: 1.2,
|
||||
},
|
||||
gsm: { signal: 79, operator: "preview", lac: "masked", cid: "masked" },
|
||||
system: { externalVoltageMv: 13240, internalVoltageMv: 4120, status: "Норма" },
|
||||
},
|
||||
},
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
});
|
||||
sessions.set(sessionRef, {
|
||||
sessionRef,
|
||||
projectRef,
|
||||
routeRef,
|
||||
routeName: "B2 direct preview",
|
||||
deviceRef,
|
||||
deviceName: "Пилотный B2",
|
||||
protocol: "INTERNAL",
|
||||
lifecycleState: "online",
|
||||
connectedAt: timestamp,
|
||||
lastSeenAt: timestamp,
|
||||
disconnectedAt: null,
|
||||
closeReasonCode: null,
|
||||
frameCount: 1842,
|
||||
byteCount: 734208,
|
||||
});
|
||||
configurationStates.set(deviceRef, {
|
||||
projectRef,
|
||||
deviceRef,
|
||||
deviceName: "Пилотный B2",
|
||||
desiredConfigurationRevisionRef: null,
|
||||
appliedConfigurationRevisionRef: null,
|
||||
appliedAt: null,
|
||||
updatedAt: timestamp,
|
||||
});
|
||||
}
|
||||
|
||||
const previewTransitions = Object.freeze({
|
||||
adapterPackage: Object.freeze({
|
||||
active: Object.freeze(["active", "retired"]),
|
||||
|
||||
Reference in New Issue
Block a user