rhombus-node-mcp
Version:
MCP server for Rhombus API
57 lines (56 loc) • 2.43 kB
JavaScript
import { buildMediaHints } from "./badge-correlation.js";
import { searchOnGuardEvents } from "./onguard-tool-api.js";
/**
* Reconstructs a single cardholder's movements as a chronological timeline of OnGuard badge taps,
* each with the still/clip hints needed to show what happened. Pure orchestration over
* searchOnGuardEvents + the shared correlation helper.
*/
export async function getBadgeTimeline(args, timeZone, requestModifiers, sessionId) {
const { events } = await searchOnGuardEvents({
cardholderQuery: args.cardholderQuery,
locationUuids: args.locationUuids,
afterMs: args.afterMs,
beforeMs: args.beforeMs,
limit: args.limit ?? 200,
}, timeZone, requestModifiers, sessionId);
// searchOnGuardEvents returns newest-first; a timeline reads chronologically.
const ordered = events
.filter((e) => e.timestampMs != null)
.sort((a, b) => (a.timestampMs ?? 0) - (b.timestampMs ?? 0));
const stops = ordered.map((e, i) => {
const next = ordered[i + 1];
const gapToNextSeconds = next?.timestampMs != null && e.timestampMs != null
? Math.round((next.timestampMs - e.timestampMs) / 1000)
: undefined;
const { clipHint, stillHint } = buildMediaHints({ deviceUuid: e.deviceUuid, timestampMs: e.timestampMs }, args.clipPaddingSeconds);
return {
timestampMs: e.timestampMs,
datetime: e.datetime,
deviceUuid: e.deviceUuid,
area: e.areaEntering ?? e.areaExiting,
label: e.label,
isAnomaly: e.isAnomaly,
clipHint,
stillHint,
gapToNextSeconds,
};
});
// The sequence of areas traversed, collapsing consecutive repeats.
const path = [];
for (const stop of stops) {
if (stop.area && stop.area !== path[path.length - 1]) {
path.push(stop.area);
}
}
// cardholderQuery is full-text, so it can match more than one person — surface that so the agent
// can disambiguate rather than silently merge two people's movements.
const distinctCardholders = [
...new Set(ordered.map((e) => e.cardholderName).filter((n) => !!n)),
];
return {
cardholderName: distinctCardholders[0],
ambiguousCardholders: distinctCardholders.length > 1 ? distinctCardholders : undefined,
stops,
path,
};
}