Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/services/admin/kwp-contract-admin.server.ts
T

99 lines
3.7 KiB
TypeScript

import { getDbClient } from "@hivegrid/db/client.server";
import { runWithRlsContext } from "@hivegrid/db/rls-context.server";
import type {
KwpContractAlarmInput,
KwpContractDiffVM,
} from "@hivegrid/view-models";
import { KWP_PROJECT_CAPABILITY } from "@hivegrid/integrations/kwp-resource-client.server";
const MAX_DIFF_PATHS = 100;
function redactedDiff(value: unknown): KwpContractDiffVM | null {
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
const diff = (value as Record<string, unknown>).diff;
if (!diff || typeof diff !== "object" || Array.isArray(diff)) return null;
const row = diff as Record<string, unknown>;
const paths = (key: string) => Array.isArray(row[key])
? row[key]!.filter((item): item is string => typeof item === "string").slice(0, MAX_DIFF_PATHS)
: [];
return {
added: paths("added"),
removed: paths("removed"),
changed: paths("changed"),
truncated: row.truncated === true,
};
}
export async function getKwpContractAdminSnapshot(
actorUserId: string,
): Promise<readonly KwpContractAlarmInput[]> {
return runWithRlsContext({ userId: actorUserId }, async () => {
const db = getDbClient();
const states = await db.kwpCapabilityState.findMany({
where: { capability: KWP_PROJECT_CAPABILITY, status: "paused" },
orderBy: [{ pausedAt: "desc" }, { updatedAt: "desc" }],
take: 200,
});
if (states.length === 0) return [];
const tenantIds = [...new Set(states.map((row) => row.tenantId))];
const connectionPairs = states.map((row) => ({
tenantId: row.tenantId,
dataConnectionId: row.dataConnectionId,
}));
const [tenants, reports, snapshots] = await Promise.all([
db.tenant.findMany({
where: { id: { in: tenantIds } },
select: { id: true, name: true },
}),
db.kwpErrorReport.findMany({
where: {
capability: KWP_PROJECT_CAPABILITY,
resolvedAt: null,
OR: connectionPairs,
},
orderBy: { createdAt: "desc" },
}),
db.kwpApiContractSnapshot.findMany({
where: {
capability: KWP_PROJECT_CAPABILITY,
OR: connectionPairs,
},
orderBy: { validatedAt: "desc" },
}),
]);
const tenantNames = new Map(tenants.map((row) => [row.id, row.name]));
const pairKey = (tenantId: string, connectionId: string) => `${tenantId}\u0000${connectionId}`;
const latestReports = new Map<string, (typeof reports)[number]>();
for (const report of reports) {
const key = pairKey(report.tenantId, report.dataConnectionId);
if (!latestReports.has(key)) latestReports.set(key, report);
}
const latestSnapshots = new Map<string, (typeof snapshots)[number]>();
for (const snapshot of snapshots) {
const key = pairKey(snapshot.tenantId, snapshot.dataConnectionId);
if (!latestSnapshots.has(key)) latestSnapshots.set(key, snapshot);
}
return states.map((state) => {
const key = pairKey(state.tenantId, state.dataConnectionId);
const report = latestReports.get(key);
const snapshot = latestSnapshots.get(key);
return {
id: state.id,
tenantId: state.tenantId,
tenantName: tenantNames.get(state.tenantId) ?? state.tenantId,
connectionId: state.dataConnectionId,
reasonCode: state.reasonCode,
observedFingerprint: state.observedFingerprint,
adapterRevision: state.adapterRevision,
capabilityRevision: state.revision,
pausedAt: state.pausedAt?.toISOString() ?? null,
lastCheckedAt: state.lastCheckedAt?.toISOString() ?? null,
lastValidatedAt: snapshot?.validatedAt.toISOString() ?? null,
diff: redactedDiff(report?.redactedDetails),
};
});
});
}